sizeof()具有零长度数组成员的结构

时间:2019-09-13 15:47:49

标签: c gcc sizeof c99 flexible-array-member

我对C语言中的sizeof()输出感到困惑。说我有:

struct foo {
    char a;
    char b;
    char c;
    char d[0];
};

我希望sizeof(struct foo)是4。但是,用gcc编译后它返回3。另外,在使用严格设置-pedantic-errors编译代码时,会出现编译器错误。

有人可以帮助我了解这种行为吗?

2 个答案:

答案 0 :(得分:7)

数组大小为0不合法。 C standard中有关数组声明符的第6.7.6.2p1节指出:

  

除了可选的类型限定符和关键字static之外,[   并且]可以分隔表达式或   *如果它们定界表达式(指定数组的大小),则该表达式应为整数类型。如果表达   是一个常量表达式,其值应大于零。   元素类型不得为不完整或函数类型。的   可选的类型限定符和关键字static将出现   仅在带有数组的函数参数声明中   类型,然后仅在最外面的数组类型派生。

因此,因为这违反了约束,所以此定义将调用undefined behavior

话虽如此,有些编译器允许长度为零的数组作为struct的最后一个成员作为扩展名。 GCC does this。在这种情况下,它的作用与灵活数组成员相同。

符合标准的方法是将尺寸留空:

struct foo {
    char a;
    char b;
    char c;
    char d[];
};

在两种情况下,结构体的大小均不包含柔性数组成员,这就是为什么大小为3而不是4的原因(尽管结构中是否存在填充取决于实现)。这也意味着这样的结构不能成为数组的成员(至少在没有一些麻烦的手动指针操作的情况下如此)。

使用这种结构的方法是为其动态分配空间以及最后一个成员的许多元素。例如:

struct foo *my_foo = malloc(sizeof(*my_foo) + (sizeof(char) * number_of_elements));

答案 1 :(得分:1)

char d[0]是一个大小为0的字符数组。这意味着自sizeof(char) * 0 = 0起,它不占用任何空间。

相关问题