VS 2005 bug
struct HashTableItem
{
void* value;
char* key;
struct HashTableItem* next;
};
struct HashTable
{
struct HastTableItem * _items [HASH_TABLE_SIZE];
int * Contains;
};
! HASH_TABLE_SIZE не задан
массив неопределённого размера может быть только в конце
ну дык а куда он должен поместить Contains, если размер предыдущего массива не известен?
Это проблема не только VC2005 (на VC++ 6.0 второй вариант также не компилируется)
gcc работает в обоих случаях
ну да понятно ,это проблема не студии а компилятора конечно
возможно. Сейчас в стандарте гляну.
> gcc работает в обоих случаях
Это не аргумент. По умолчанию gcc работает очень далеко не по стандарту.
#define HASH_TABLE_SIZE
struct HashTableItem
{
void* value;
char* key;
struct HashTableItem* next;
};
struct HashTable
{
int * Contains;
struct HastTableItem * _items [HASH_TABLE_SIZE];
};
int main(int argc, char* argv[])
{ struct HashTable a;
printf("%d\n",sizeof(a;
return 0;
}
тут дело не только в стандарте, а почему в одном случае работает, а в другом нет?)
действительно
странно, что 4. По умолчанию выравнивание на 8.
А причем здесь выравнивание? Из того, что sizeof(a)==4, следует, что либо там один 32-битный указатель, либо два 16-битных указателя, либо char занимает не один байт...
sizeof структуры, вроде, выдает размер структуры, а не суммы его элементов
sizeof {char} = 1
sizeof {int} = 4
sizeof {char, int} = 8
sizeof {int, char} = 8
sizeof {char, int, int} = 12
Бред какой-то. В установках проекта установлено выравнивание на 8.
а размер всей структуры должен быть кратен самому большому элементу в ней
На своем первом коммерческом проекте (надо было написать простенькую линейную базу данных) столкнулся с тем, что один и тот же мой код, скомпилированный на разных компах, не мог прочитать созданную самим собой базу. Оказалось, что в параметрах одного проекта стояло выравнивание на 4, а в другом - на 8. В итоге одна и та же структура бросалась в файл одним образом, а считывалась другим. И с сииком по файлу проблемы были.
он должен сделать указатель а не массив в таком случаеЭэээ... Ты чо, чувак?
struct HastTableItem * _items [HASH_TABLE_SIZE]; - это массив указателей на HashTableItem, читай precedence of operators (или что-то в этом роде).
Указатель на массив указателей - это
HashTableItem * (*_items) [HASH_TABLE_SIZE];
а вообще лучше через тайпдеф написать.
Фишка в том, что это чисто синтаксически различные вещи, к генерации кода никакого отношения не имеющие. Статический массив и указатель на массив - это разные типы и компилятор, естественно, не должен самовольно превращать одно в другое. Кстати, массивы разной длины - это тоже разные типы, поэтому ничего особо интересного с указателем на массив нулевой длины ты сделать не сможешь (в плюсах по крайней мере при попытке присвоить ему указатель на реальный массив выпадает ошибка, нужно явно тайпкастить).
Цитата из хелпа:
A member of a structure or bit field contains a zero-sized array that is not the last member.Причём это фишка помеченная как microsoft-specific (и работающая только с /Le так что я сильно не уверен, что она есть в стандарте.
Because you can have a zero sized array as the last member of the struct, you must specify its size when you allocate the struct.
If the zero sized array is not the last member of the struct, the compiler can't calculate the offset for the remaining fields.
Как гцц разбирается с zero-sized arrays я не знаю.
никопилица? да за объявление объектов неполного типа она тебе бригаду с паяльником на дом вызывать должна
del
Оставить комментарий
Polly_love
#define HASH_TABLE_SIZEstruct HashTableItem
{
void* value;
char* key;
struct HashTableItem* next;
};
struct HashTable
{
int * Contains;
struct HastTableItem * _items [HASH_TABLE_SIZE];
};