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

sizeof() a struct with a zero length array member

我对 C 中的 sizeof() 输出感到困惑。假设我有:

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

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

谁能帮我理解这种行为?

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

In addition to optional type qualifiers and the keyword static , the [ and ] may delimit an expression or * . If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. The element type shall not be an incomplete or function type. The optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

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

也就是说,一些编译器允许零长度数组作为 struct 的最后一个成员作为扩展。 GCC does this。在这种情况下,它的工作方式与灵活数组成员相同。

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

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

在这两种情况下,灵活的数组成员都不包含在结构的大小中,这就是为什么您得到的大小是 3 而不是 4(尽管结构中是否存在填充取决于实现) .这也意味着这样的结构不能是数组的成员(至少在没有一些可疑的手动指针操作的情况下不能)。

您使用这种结构的方式是为其动态分配 space 加上最后一个成员的一些元素。例如:

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

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