Таким образом, 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 даже думать о том, чтобы сделать это?