struct has an illegal zero-sized array
От: Аноним  
Дата: 06.01.10 16:10
Оценка:
Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?

/** Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
struct logvol_integrity_desc_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;
  udf_Uint32_t    freespace_table[0];
  udf_Uint32_t    size_table[0];
  udf_Uint8_t     imp_use[0]; 
} GNUC_PACKED;
Re: struct has an illegal zero-sized array
От: Vamp Россия  
Дата: 06.01.10 16:18
Оценка:
А>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?
Массивы из нуля элементов запрещены. А нафига они?
Да здравствует мыло душистое и веревка пушистая.
Re[2]: struct has an illegal zero-sized array
От: cppguy  
Дата: 06.01.10 16:25
Оценка:
Здравствуйте, Vamp, Вы писали:

А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?

V>Массивы из нуля элементов запрещены. А нафига они?
Re[2]: struct has an illegal zero-sized array
От: cppguy  
Дата: 06.01.10 16:28
Оценка: -2
Здравствуйте, Vamp, Вы писали:

А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?

V>Массивы из нуля элементов запрещены. А нафига они?

стандартом они не запрещены, код из модуля ядра линукса
http://sourceforge.net/projects/linux-udf/
Re[3]: struct has an illegal zero-sized array
От: denisko http://sdeniskos.blogspot.com/
Дата: 06.01.10 16:35
Оценка:
Здравствуйте, cppguy, Вы писали:

C>Здравствуйте, Vamp, Вы писали:


А>>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?

V>>Массивы из нуля элементов запрещены. А нафига они?

C>стандартом они не запрещены, код из модуля ядра линукса

C>http://sourceforge.net/projects/linux-udf/
Емнип, если просто массив нулевой длинны -- он должен быть 1 и последним элементом в структуре. Используй boost::array<T,0> Если тебе эти поля дороги как память.
<Подпись удалена модератором>
Re[4]: struct has an illegal zero-sized array
От: cppguy  
Дата: 06.01.10 16:41
Оценка: :)
не знаю на сколько то хорошо, но проблема компиляции решилась помещением массивов нулевой длинны в union.
Re: struct has an illegal zero-sized array
От: IROV..  
Дата: 06.01.10 18:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?


А>
А>/** Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
А>struct logvol_integrity_desc_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;
А>  udf_Uint32_t    freespace_table[0];
А>  udf_Uint32_t    size_table[0];
А>  udf_Uint8_t     imp_use[0]; 
А>} GNUC_PACKED;
А>


imp_use[0] используется как указание начала масива, а масив располагается дальше по стеку/памяти, встречал в проектах как "оптимизация"
я не волшебник, я только учусь!
Re: struct has an illegal zero-sized array
От: Кодт Россия  
Дата: 06.01.10 19:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Пытаюсь скомпилять код из 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 байта.
Перекуём баги на фичи!
Re[2]: struct has an illegal zero-sized array
От: remark Россия http://www.1024cores.net/
Дата: 08.01.10 08:15
Оценка:
Здравствуйте, Кодт, Вы писали:

А>>Пытаюсь скомпилять код из linux на msvc, как убороть проблему ошибки C2229?


К>Не знаю, как победить нахаляву, а как победить некоторым рефакторингом — так это просто


Хммм... А почему просто не добавить union:

struct logvol_integrity_desc_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;
  union {
  udf_Uint32_t    freespace_table[0];
  udf_Uint32_t    size_table[0];
  udf_Uint8_t     imp_use[0]; 
  };
} GNUC_PACKED;


Тут проблема не в массиве нулевой длины — студия их есть, а в том, что массив нулевой длины не последний в структуре.
Вариант с union студия должна съесть.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: struct has an illegal zero-sized array
От: Кодт Россия  
Дата: 14.01.10 20:57
Оценка:
Здравствуйте, remark, Вы писали:

R>Тут проблема не в массиве нулевой длины — студия их есть, а в том, что массив нулевой длины не последний в структуре.

R>Вариант с union студия должна съесть.

Ааа, ну если студия съест, то супер. Я было решил, что дело в размере.
Перекуём баги на фичи!
Re[2]: struct has an illegal zero-sized array
От: Skorodum Россия  
Дата: 15.01.10 07:42
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Массивы из нуля элементов запрещены. А нафига они?


Это расширение gcc, активно используемое в ядре линукса. Не знаю зачем их несколько может понадобится в структуре, но вот один последний такой элемент часто используется для обращения к данным,записанным за конец структуры.
gcc [0]
Re[4]: struct has an illegal zero-sized array
От: Кодт Россия  
Дата: 15.01.10 09:11
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Ааа, ну если студия съест, то супер. Я было решил, что дело в размере.


Нифига не супер. Съесть-то она съест, только посчитает [1] вместо [0].
struct Foo
{
    int x;
    union
    {
        int y[0];
        char z[0];
    };
};

struct FooBar
{
    char data[sizeof(Foo) + sizeof(int)*3];
    Foo* foo() { return (Foo*)data; }
    int* yyy() { return (int*)(data + sizeof(Foo)); }
};

int main()
{
    FooBar fb;
    Foo& f = *fb.foo();
    int* y =  fb.yyy();
    
    f.y[0] = 123456789;
    f.y[1] = 987654321;
    f.y[1] = 555555555;
    printf("%d : %d %d", sizeof(Foo), y[0], y[1]);
    // VC  --> 8 : 987654321 555555555
    // gcc --> 4 : 123456789 987654321
}

То есть, для интерпретации уже готового пакета как заголовок+хвост это пригодно, а для построения такого пакета — увы.
Перекуём баги на фичи!
Re[3]: struct has an illegal zero-sized array
От: Кодт Россия  
Дата: 15.01.10 09:27
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>Это расширение gcc, активно используемое в ядре линукса. Не знаю зачем их несколько может понадобится в структуре, но вот один последний такой элемент часто используется для обращения к данным,записанным за конец структуры.


Очевидно, зачем. Если данные за концом структуры могут иметь разный тип (видимо, в зависимости от содержания данной структуры).
Например, у битмапа есть общий заголовок, после которого идут 8-, 16-, 24- или 32-битные пикселы.
Перекуём баги на фичи!
Re[4]: struct has an illegal zero-sized array
От: Skorodum Россия  
Дата: 15.01.10 13:00
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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);


Поясните, пожалуйста, подробнее зачем таких переменных больше одной?
[0]
Re[5]: struct has an illegal zero-sized array
От: remark Россия http://www.1024cores.net/
Дата: 15.01.10 13:14
Оценка: 34 (2)
Здравствуйте, 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.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: struct has an illegal zero-sized array
От: Skorodum Россия  
Дата: 15.01.10 13:31
Оценка:
Здравствуйте, 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>

[0] gcc
Re[7]: struct has an illegal zero-sized array
От: remark Россия http://www.1024cores.net/
Дата: 15.01.10 13:46
Оценка:
Здравствуйте, 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)" не будет работать, а именно так все и пишут. Смысла тогда добавлять такую поддержку нулевых массивов мало...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: struct has an illegal zero-sized array
От: remark Россия http://www.1024cores.net/
Дата: 15.01.10 13:47
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>gcc показывает что не зависит. И bar и baz — всего лишь адрес, в структуре такой переменной нет:


S>
S>struct Foo
S>{
S>    int a;
S>    long long k[0];
S>    int b[0];
S>    short c[0];
S>    char d[0];
S>};

S>struct Bar
S>{
S>    int a;
S>};


S>int main()
S>{
S>    Foo f;
S>    if((int)&f + sizeof(Foo) == int(f.k) &&
S>       (int)&f + sizeof(Foo) == int(f.b) &&
S>       (int)&f + sizeof(Foo) == int(f.c) &&
S>       (int)&f + sizeof(Foo) == int(f.d) &&
S>       sizeof(Bar) == sizeof(Foo))
S>        std::cout << "no difference" << std::endl;
S>    return 0;
S>}
S>


А если а объявить как char, а не как int?


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: struct has an illegal zero-sized array
От: Skorodum Россия  
Дата: 15.01.10 13:52
Оценка:
Здравствуйте, remark, Вы писали:

R>А если а объявить как char, а не как int?


no difference



gcc version 3.4.5
Re[9]: struct has an illegal zero-sized array
От: remark Россия http://www.1024cores.net/
Дата: 15.01.10 14:02
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>Здравствуйте, remark, Вы писали:


R>>А если а объявить как char, а не как int?


S>no difference


S>gcc version 3.4.5


Не может так быть.

#include <stdio.h>
#include <stdint.h>

struct Y
{
  char ch;
};

struct X
{
  char ch;
  uint64_t arr [0];
};

int main()
{
  printf("sizeof(Y)=%u\n", sizeof(Y));
  printf("sizeof(X)=%u\n", sizeof(X));
}


g++ -v
gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)

sizeof(Y)=1
sizeof(X)=4


Просто баг в gcc 3.4.5. Проапдейть до более новой версии.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.