VS 2005 bug

Polly_love

#define HASH_TABLE_SIZE
struct HashTableItem
{
void* value;
char* key;
struct HashTableItem* next;
};
struct HashTable
{
int * Contains;
struct HastTableItem * _items [HASH_TABLE_SIZE];
};

Polly_love

#define HASH_TABLE_SIZE
struct HashTableItem
{
void* value;
char* key;
struct HashTableItem* next;
};
struct HashTable
{
struct HastTableItem * _items [HASH_TABLE_SIZE];
int * Contains;
};

Polly_love

первый из предложенных вариантов компилится, второй нет :-D
! HASH_TABLE_SIZE не задан

Chupa

всё правильно
массив неопределённого размера может быть только в конце

maggi14

ну дык а куда он должен поместить Contains, если размер предыдущего массива не известен?

ryshiy28

Это проблема не только VC2005 (на VC++ 6.0 второй вариант также не компилируется)

Polly_love

он должен сделать указатель а не массив в таком случае
gcc работает в обоих случаях

Polly_love

ну да понятно ,это проблема не студии а компилятора конечно

maggi14

> он должен сделать указатель а не массив в таком случае
возможно. Сейчас в стандарте гляну.
> gcc работает в обоих случаях
Это не аргумент. По умолчанию gcc работает очень далеко не по стандарту.

ryshiy28

Следующий код выводит на stdout число 4 [VC++ 6.0] (похоже массив _items отсутствует)
#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;
}
 

Polly_love

тут дело не только в стандарте, а почему в одном случае работает, а в другом нет?)

Polly_love

действительно

maggi14

странно, что 4. По умолчанию выравнивание на 8.

tamusyav

А причем здесь выравнивание? Из того, что sizeof(a)==4, следует, что либо там один 32-битный указатель, либо два 16-битных указателя, либо char занимает не один байт...

maggi14

sizeof структуры, вроде, выдает размер структуры, а не суммы его элементов

maggi14

опытным путем установил, что:
sizeof {char} = 1
sizeof {int} = 4
sizeof {char, int} = 8
sizeof {int, char} = 8
sizeof {char, int, int} = 12
Бред какой-то. В установках проекта установлено выравнивание на 8.

boikodima1

обычно каждый элемент структуры выравниваетсу по его размеру (тоесть смещение int в структуре должно быть кратно 4 итп)
а размер всей структуры должен быть кратен самому большому элементу в ней

maggi14

На своем первом коммерческом проекте (надо было написать простенькую линейную базу данных) столкнулся с тем, что один и тот же мой код, скомпилированный на разных компах, не мог прочитать созданную самим собой базу. Оказалось, что в параметрах одного проекта стояло выравнивание на 4, а в другом - на 8. В итоге одна и та же структура бросалась в файл одним образом, а считывалась другим. И с сииком по файлу проблемы были.

bleyman

он должен сделать указатель а не массив в таком случае
Ээээ... Ты чо, чувак?
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.
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.
Причём это фишка помеченная как microsoft-specific (и работающая только с /Le так что я сильно не уверен, что она есть в стандарте.
Как гцц разбирается с zero-sized arrays я не знаю.

buka

баг говоришь?
никопилица? да за объявление объектов неполного типа она тебе бригаду с паяльником на дом вызывать должна

Polly_love

del
Оставить комментарий
Имя или ник:
Комментарий: