Здравствуйте, Vamp, Вы писали:
А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229? V>Массивы из нуля элементов запрещены. А нафига они?
Здравствуйте, Vamp, Вы писали:
А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229? V>Массивы из нуля элементов запрещены. А нафига они?
Здравствуйте, cppguy, Вы писали:
C>Здравствуйте, Vamp, Вы писали:
А>>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229? V>>Массивы из нуля элементов запрещены. А нафига они?
C>стандартом они не запрещены, код из модуля ядра линукса C>http://sourceforge.net/projects/linux-udf/
Емнип, если просто массив нулевой длинны -- он должен быть 1 и последним элементом в структуре. Используй boost::array<T,0> Если тебе эти поля дороги как память.
Здравствуйте, Аноним, Вы писали:
А>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?
Не знаю, как победить нахаляву, а как победить некоторым рефакторингом — так это просто А>
А>struct logvol_integrity_desc_header_s /* выделяем заголовок пакета в отдельную структуру */
А>{
А> udf_tag_t tag;
А> udf_timestamp_t recording_time;
А> udf_Uint32_t integrity_type;
А> udf_extent_ad_t next_integrity_ext;
А> udf_Uint8_t logvol_contents_use[32];
А> udf_Uint32_t i_partitions;
А> udf_Uint32_t imp_use_len;
};
struct logvol_integrity_desc_fictive /* фиктивная структура, описывающая пакет целиком */
{
struct logvol_integrity_desc_header_s header; /* а если это С++ - то проще унаследовать */union
{
А> udf_Uint32_t freespace_table[1];
А> udf_Uint32_t size_table[1];
А> udf_Uint8_t imp_use[1];
};
А>};
А>
Правда, рефакторинг выйдет кровавый... (а впрочем, это и хорошо, ибо все ошибки будут пойманы на стадии компиляции).
Возможно, что достаточно просто обрамить три последних поля (фиктивные массивы) в юнион, и указать им длину в 1, а не в 0.
И затем обязательно отследить по всей программе, что размер структуры берётся правильно — без учёта этого фиктивного хвостика размером в 4 байта.
Здравствуйте, Кодт, Вы писали:
А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?
К>Не знаю, как победить нахаляву, а как победить некоторым рефакторингом — так это просто
Тут проблема не в массиве нулевой длины — студия их есть, а в том, что массив нулевой длины не последний в структуре.
Вариант с union студия должна съесть.
Здравствуйте, remark, Вы писали:
R>Тут проблема не в массиве нулевой длины — студия их есть, а в том, что массив нулевой длины не последний в структуре. R>Вариант с union студия должна съесть.
Ааа, ну если студия съест, то супер. Я было решил, что дело в размере.
Здравствуйте, Vamp, Вы писали:
V>Массивы из нуля элементов запрещены. А нафига они?
Это расширение gcc, активно используемое в ядре линукса. Не знаю зачем их несколько может понадобится в структуре, но вот один последний такой элемент часто используется для обращения к данным,записанным за конец структуры.
Здравствуйте, Skorodum, Вы писали:
S>Это расширение gcc, активно используемое в ядре линукса. Не знаю зачем их несколько может понадобится в структуре, но вот один последний такой элемент часто используется для обращения к данным,записанным за конец структуры.
Очевидно, зачем. Если данные за концом структуры могут иметь разный тип (видимо, в зависимости от содержания данной структуры).
Например, у битмапа есть общий заголовок, после которого идут 8-, 16-, 24- или 32-битные пикселы.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Skorodum, Вы писали:
S>>Это расширение gcc, активно используемое в ядре линукса. Не знаю зачем их несколько может понадобится в структуре, но вот один последний такой элемент часто используется для обращения к данным,записанным за конец структуры.
К>Очевидно, зачем. Если данные за концом структуры могут иметь разный тип (видимо, в зависимости от содержания данной структуры). К>Например, у битмапа есть общий заголовок, после которого идут 8-, 16-, 24- или 32-битные пикселы.
Как я понимаю
stract foo
{
int a;
int b[0];
short c[0];
};
и b и с — это ведь просто адрес прямо за концом структуры:
foo f;
f.b == f.c;
f.b == int(&f) + sizeof(foo);
Поясните, пожалуйста, подробнее зачем таких переменных больше одной?
Здравствуйте, Skorodum, Вы писали:
S>и b и с — это ведь просто адрес прямо за концом структуры:
Синтаксический сахар за борт, полагаю, что типы нулевых массивов влияют на выравнивание. Во-первых, это должен быть не просто "адрес за концом структуры", а адрес, зависящий от типа нулевого массива.
Т.е. в таком коде адреса bar и baz могут быть разными:
struct X
{
char foo [1];
char bar [0];
int baz [0];
};
Во-вторых, типы нулевых массивов должны влиять и на размер структуры. Это необходимо для работы идиомы выделения таких объектов — "malloc(sizeof(X) + sizeof(Y) * N)".
Т.е. в таком коде, включив или bar или baz, ты получишь разный sizeof(X):
struct X
{
char foo [1];
//char bar [0];
//int baz [0];
};
Т.о. если за структрурой могут лежать массивы действительно разных типов, то помещение нескольких нулевых массивов в структуру необходимо. В противном случае придётся жёстко заморачиваться с max_align_t.
Здравствуйте, remark, Вы писали:
R>Синтаксический сахар за борт, полагаю, что типы нулевых массивов влияют на выравнивание. Во-первых, это должен быть не просто "адрес за концом структуры", а адрес, зависящий от типа нулевого массива. R>Т.е. в таком коде адреса bar и baz могут быть разными: R>
R>struct X
R>{
R> char foo [1];
R> char bar [0];
R> int baz [0];
R>};
R>
gcc показывает что не зависит. И bar и baz — всего лишь адрес, в структуре такой переменной нет:
struct Foo
{
int a;
long long k[0];
int b[0];
short c[0];
char d[0];
};
struct Bar
{
int a;
};
int main()
{
Foo f;
if((int)&f + sizeof(Foo) == int(f.k) &&
(int)&f + sizeof(Foo) == int(f.b) &&
(int)&f + sizeof(Foo) == int(f.c) &&
(int)&f + sizeof(Foo) == int(f.d) &&
sizeof(Bar) == sizeof(Foo))
std::cout << "no difference" << std::endl;
return 0;
}
R>Во-вторых, типы нулевых массивов должны влиять и на размер структуры. Это необходимо для работы идиомы выделения таких объектов — "malloc(sizeof(X) + sizeof(Y) * N)". R>Т.е. в таком коде, включив или bar или baz, ты получишь разный sizeof(X): R>
R>struct X
R>{
R> char foo [1];
R> //char bar [0];
R> //int baz [0];
R>};
R>
То же самое, gcc показывает что не зависит. Нулевые массивы не добавляют к структуре ничего.
R>Т.о. если за структрурой могут лежать массивы действительно разных типов, то помещение нескольких нулевых массивов в структуру необходимо. В противном случае придётся жёстко заморачиваться с max_align_t.
Вот это правда, с выравниванием заморачиваются.
R>
Здравствуйте, Skorodum, Вы писали:
R>>Во-вторых, типы нулевых массивов должны влиять и на размер структуры. Это необходимо для работы идиомы выделения таких объектов — "malloc(sizeof(X) + sizeof(Y) * N)". R>>Т.е. в таком коде, включив или bar или baz, ты получишь разный sizeof(X): R>>
R>>struct X
R>>{
R>> char foo [1];
R>> //char bar [0];
R>> //int baz [0];
R>>};
R>>
S>То же самое, gcc показывает что не зависит. Нулевые массивы не добавляют к структуре ничего.
Хммм... что-то я не уверен. Как так может быть? Тогда "malloc(sizeof(X) + sizeof(Y) * N)" не будет работать, а именно так все и пишут. Смысла тогда добавлять такую поддержку нулевых массивов мало...