Это безопасно выделить слишком мало места (если вы знаете, что вам это не понадобится)?

Таким образом, C99 благословил общепринятый «гибкий членский член», чтобы позволить нам сделать struct , которые могут быть объединены в соответствии с нашими требованиями размера. Я подозреваю, что это совершенно безопасно в большинстве зменных реализаций, но это юридически в C для «недооцененного», если мы знаем в определенных ситуациях, что нам не понадобятся членов структуры ?

Абстрактный пример

Скажем, у меня есть тип:

struct a {
  bool   data_is_x;
  void * data;
  size_t pos;
};

Если data_is_x , то тип данных - это тип, который необходимо использовать POS Отказ В противном случае функции, работающие с этим struct , не понадобятся POS для этой конкретной копии структуры . По сути, структура содержит информацию о том, имеет ли он POS элемент , и эта информация не будет изменена в течение работы struct (снаружи злого бода, который все равно будет много сломать). Это безопасно сказать:

struct a *a = malloc(data_is_x ? sizeof(struct a) : offsetof(struct a, pos));

, который выделит пространство для POS , только если он нужен? Или он нарушает ограничение для использования литого пространства, которое слишком мало до структуры указатель , даже если вы никогда не используете соответствующие участники?

Бетон примера

Мой реальный случай Немного вовлечена; Это здесь в основном, чтобы вы могли понять Почему Я хочу сделать это:

typedef struct {
  size_t size;
  void * data;
  size_t pos;
} mylist;

Код для MyList_Create Указывает, что для Размер> 0 , Данные - это массив смежных данных, которые представляют собой размер элементы длиной (какой бы ни был предметом), но это для размер == 0 Это текущий узел вдвое -Бореженный список, содержащий элементы. Все функции, которые работают с MyList , проведут ли размер == 0 . Если это так, они будут справиться с данными в виде связанного списка с «текущим» индексом, являющимся в каком узле данных . Если нет, они обрабатывают данные в качестве массива с «текущим» индексом, хранящимся в POS .

Теперь, если размер == 0 Нам действительно не нужен POS , но если размер> 0 . Итак, мой вопрос, это законно делать это:

mylist *list = malloc(size ? sizeof(mylist) : offsetof(mylist, pos));

, если мы гарантируем (по штрафу не определеному поведению), что, в то время как размер == 0 , мы никогда не постараемся (или надо) доступа к POS участника? Или он говорит где-то в стандарте, что UB даже думать о том, чтобы сделать это?

14
задан Chris Lutz 9 September 2011 в 02:22
поделиться