C 结构成员的偏移量用作数组长度时发生编译错误

C 结构成员的偏移量用作数组长度时发生编译错误,c,gcc,C,Gcc,当使用GCC4.8.3编译下面的代码时,我收到一个错误,上面写着“arrTest.c:12:4:error:variable size object可能未初始化”。但使用GCC4.1编译时,同样的代码也可以很好地编译。有人能帮我修一下吗 #define OFFSET(structure, member) /* byte offset of member in structure*/\ ((const int) &(((structure *) 0)

当使用GCC4.8.3编译下面的代码时,我收到一个错误,上面写着“arrTest.c:12:4:error:variable size object可能未初始化”。但使用GCC4.1编译时,同样的代码也可以很好地编译。有人能帮我修一下吗

#define OFFSET(structure, member)    /* byte offset of member in structure*/\
                ((const int) &(((structure *) 0) -> member))

typedef struct test{
   int a;
   char b;
   int c;
}test;

void main()
{
   int arr[OFFSET(test, b)] = {0};

   printf("%d %d\n", arr[0], OFFSET(test, b));

   return;
}

不过,删除阵列初始化将解决此问题。但是,在我的代码中有很多这样的实例。所以我不想到处去修改。我想知道GCC4.8中是否有任何方法可以通过一些编译标志或修改宏的定义来解决这个问题,因为GCC4.1可以干净地编译相同的代码。

在现代C中,您的
OFFSET
宏是不正确的,因为取消引用空指针是未定义的行为;此外,现代C语言中没有规定任意指针算法产生编译时常量,这就是为什么gcc抱怨数组大小可变的原因

幸运的是,现代C提供了一个完全定义了行为并产生编译时常量的

#include <stddef.h>
#define OFFSET(structure,member) offsetof(structure, member)

// rest of code

尝试使用C库
offsetof()
宏。在GCC中,它使用了
\u内置的偏移量()
函数,似乎工作正常。

change
int-arr[offset(test,b)]={0}
int-arr[偏移量(测试,b)]谢谢Grijesh,实际上在我的代码中有很多这样的实例。所以我不想像你建议的那样到处去修改。我想知道GCC4.8中是否有任何方法可以通过一些编译标志或修改宏的定义来解决这个问题,因为GCC4.1可以干净地编译相同的代码。我相信应该有一些方法。您还应该在底部的问题注释中添加此信息。我假设
偏移量
不是编译时常量(尽管外观如此),因此
arr
将是OP代码中的可变长度数组<相反,code>offsetof
是一个编译时整数常量,导致“正常”数组定义。
#ifdef __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC__MINOR__ >= 8))
#    include <stddef.h>
#    define OFFSET(structure,member) offsetof(structure, member)
#else
#    define OFFSET(structure, member)    /* byte offset of member in structure*/\
            ((const int) &(((structure *) 0) -> member))
#endif