Здравствуйте. У меня в языке С задана структура: Код (Text): typedef struct _A { int a; char b[0]; } A; Собственно, вопросы: 1. равно sizeof(A) == sizeof(int)? 2. насколько такое определение структуры вообще корректно (VS выдаёт варнинги)?
Возможность такого определения зависит от компилятора и стандарта. Если поддерживает, то sizeof(A) будет равно sizeof(int).
Читаем стандарт C ISO/IEC 9899 Т.е. вообще говоря нельзя так и стандарт говорит что константы должны быть больше 0!
Если размер данных заранее неизвестен. Например, Код (Text): typedef struct { size_t length; char data[0]; } VArray; При создании этой структуры с помощью malloc выделяют памяти sizeof(VArray) + length и обращаются к данным через поле data (ведь контроля границ массива нет).
Затем, что в вашем варианте надо выделять память 2 раза, а в моём только один раз. А ещё если данные уже пришли в этом формате. Например, мы прочитали пакет с сокета.
Я не говорю, что так надо делать всегда. Я показываю, что массивы нулевой длины могут быть полезны и это не такое уж и причудливое объявление.
Booster Например для реализации строки таким образом: Код (Text): struct my_string { size_t size, len; char str[0] }; struct my_string* new_my_string(size_t size) { struct my_string *str = malloc (sizeof(*str) + size); str.size = size; str.len = 0; return str; } При таком подходе можно сэкономить на количестве malloc'ов и разадресаций. Но есть и ещё один бонус: бинарные структуры в файлах и всяческих сетевых протоколах, подчастую переменного размера.
KIV Если подсмотреть в виндовые хедеры, то можно увидеть, что эту проблему решают массивом в 1 элемент.
Если память выделяется через malloc, которой мы просто обязаны явно указывать размер, тогда нет смысла писать именно 0. Можно написать любое число, например 1, и не ломать голову над ворнингами компиляторов. Если волнует вопрос использования sizeof+доп.размер, то определить константу на единицу меньше sizeof, и вместо sizeof использовать ее.
srm смысл такой огород городить ??? фактически вы пытаетесь дублировать механизм установки метки через структуру и заморачиваетесь вопросом размера
Так не получится: Код (Text): struct A { int x; char s[0]; }; sizeof(A) == 4; struct A { int x; char s[1]; }; sizeof(A) == 8; Плюс ещё выравнивание полей структуры... Если нужно так: Код (Text): struct A { short x; char s[1]; }; то вообще хз что получится. sizeof(A) - sizeof(A::s) ничего хорошего не даст, т.к. в зависимости от выравнивания может быть 8 - 1, а может 4 - 1. Смысл в удобстве использования.
Я никак не могу вспомнить, в каких случаях в C можно пропускать имена вышестоящих структур при обращении к полям вложенных структур. Нельзя ли здесь так же выкрутиться? Что-то типа: Код (Text): struct Header { int size; double something_else; }; struct Packet { struct Header hdr; char data[1]; }; ... { ... packet=malloc(sizeof(Header)+datasize); //packet->hdr.size=datasize; //<-- Можно ли не так, packet->size=datasize; //<-- а вот так ? ... } Или это к енумам относилось?
Dmitry_Milk В C ни в каких. В C++ в том случае, если вложенная структура безымянная: Код (Text): struct _MY_STRUCT { DWORD first; struct { DWORD second; }; } my_struct = {5, {7}}; my_struct.second; //<- обращение к члену вложенной структуры Это полезно при использовании вложенных объединений. Со структурами не помню, чтобы пригодилось.