为什么允许在struct中定义未定义的大小数组?

时间:2018-03-10 10:03:59

标签: c

当我编写以下代码时,我收到预期的错误MessageReaction

error: array size missing in 'data'

但是,当我运行相同的代码但将违规行包装在int main() { unsigned char data[]; return 0; } 内时,没有错误。

struct

有人可以向我解释为什么允许这样做吗?

2 个答案:

答案 0 :(得分:4)

后者称为"flexible array member",这是结构的特例。允许结构的最后一个成员没有大小。

  

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这被称为灵活的阵列成员。在大多数情况下,将忽略灵活数组成员。特别地,结构的尺寸好像省略了柔性阵列构件,除了它可以具有比省略意味着更多的拖尾填充。但是,当一个。 (或 - >)运算符有一个左操作数,它是一个带有灵活数组成员的结构(指针),右操作数命名该成员,它的行为就好像该成员被最长的数组替换(具有相同的元素) type)不会使结构大于被访问的对象;数组的偏移量应保持为灵活数组成员的偏移量,即使这与替换数组的偏移量不同。如果此数组没有元素,则其行为就好像它有一个元素,但如果任何尝试访问该元素或生成一个超过它的指针,则行为是未定义的。

另见example 20

前者是普通数组,不允许零大小。请参阅6.7.6.2 Array declarators

  

如果它们分隔表达式(指定数组的大小),则表达式应具有整数类型。如果表达式是常量表达式,则其值应大于零。   换句话说,语言标准是这样说的。

答案 1 :(得分:2)

在您的第一个示例中,您已定义了一个常规数组,但未给出其大小。

这在C中是不合法的。在sudo udevadm info -q path -n /dev/hidraw0之外,当你声明它时,你的数组需要一个大小,因为你以后无法设置大小:

struct

在您的第二个示例中,您已定义flexible array member

这是C中的合法操作,允许您在为int main() { unsigned char data[100]; return 0; } 分配内存时为阵列分配内存。灵活的数组成员必须是struct中的最后一个元素。

以下是基于the one from GCC's documentation的示例:

struct