Why is this initialization of a structure with a flexible array member invalid but valid with an fixed size array member?
C标准状态(强调我的意思):
21 EXAMPLE 2 After the declaration:
1 struct s { int n; double d[]; };the structure struct
s has a flexible array memberd . [...]22 Following the above declaration:
1
2
3
4 struct s t1 = { 0 }; // valid
struct s t2 = { 1, { 4.2 }}; // invalid
t1.n = 4; // valid
t1.d[0] = 4.2; // might be undefined behaviorThe initialization of
t2 is invalid (and violates a constraint) becausestruct s is treated as if it did not contain memberd .Source: C18, ?§6.7.2.1/20 + /21
我不理解"的解释,因为
如果我使用
确切地说,是将柔性数组成员初始化为由一个元素组成,然后将该元素初始化为值
在我眼里这句话毫无意义。
-
为什么标准会说
{ 4.2 } 不会初始化/表示灵活数组成员,因此该结构将被视为没有成员d ?
如果我使用固定大小的数组,此表示法将起作用并初始化成员,而不会产生任何抱怨:
1 2 3 4 5 6 7 8 9 | struct foo { int x; double y[1]; }; int main (void) { struct foo a = { 1, { 2.3 } }; } |
证据
- 为什么在结构具有柔性数组成员时此初始化无效,而在结构具有固定大小数组成员时有效?
您能详细说明吗?
我读过:
为什么灵活数组成员的静态初始化有效?
和
如何使用灵活的数组成员初始化结构
和
灵活的数组成员会导致未定义的行为吗?
和其他人,但没有一个回答我这句话想解释什么以及为什么这实际上是无效的。
相关:
- 具有灵活数组成员的结构的数组如何表现?
- 灵活阵列成员的真正好处是什么?
我想这是语言缺陷。尽管初始化灵活的数组成员可能没有任何意义,但该标准需要在某个地方解决该问题。我在任何地方都找不到这样的规范文本。
柔性数组成员的定义是C17 6.7.2.1/18:
As a special case, the last element of a structure with more than one named member may have an
incomplete array type; this is called a flexible array member. In most situations, the flexible array
member is ignored. In particular, the size of the structure is as if the flexible array member were
omitted except that it may have more trailing padding than the omission would imply.
由此我们可以了解到,灵活数组成员是不完整的数组类型。但是,除了计算结构的大小时,我们不会了解在什么情况下会忽略柔性数组成员。"在大多数情况下"无济于事,并且是缺陷–需要扩展为详尽的列表,包括在初始化列表的一部分时灵活数组成员的行为。否则,可能会假定它的行为与其他任何不完整类型的数组一样。
C17 6.2.5 / 22:
An array type of unknown size is an incomplete type.
然后初始化规则说,C17 6.7.9:
The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.
到目前为止,尚无规范性文字说明不允许我们为灵活数组成员提供初始化程序-相反。问题中的示例(C17 6.7.2.1示例21)不是规范性的,因为示例在ISO标准中不是规范性的。该示例没有提到违反了哪个约束,也没有提到必须忽略灵活数组成员的位置。
我想我可能会为此提交一份DR。
I do not understand the explanation of"because struct s is treated as if it did not contain member d".
C标准还表示:在大多数情况下,都会忽略灵活数组成员。目前尚不清楚为什么您不明白这是什么意思。如果
问这种情况为什么是明智的。在大多数情况下,我希望编译器可以支持一个定义,其中对数组初始化程序进行计数并用于设置结构大小。当然,编译器使用s
您在引用的示例中省略了一些重要的语言-这是全文:
20 EXAMPLE 2 After the declaration:
1 struct s { int n; double d[]; };the structure
struct s has a flexible array memberd . A typical way to use this is:
1
2and assuming that the call to
malloc succeeds, the object pointed to byp behaves, for most purposes, as if
p had been declared as:
1 struct { int n; double d[m]; } *p;(there are circumstances in which this equivalence is broken; in particular, the offsets of member
d might
not be the same).
IOW,只有在动态分配
一个灵活的数组成员没有大小,因此它对
IMO,这是因为当将结构声明为