是否使用未定义所有成员的结构未定义?

Eri*_*hil 13 c struct undefined-behavior language-lawyer

在块范围内考虑此代码:

struct foo { unsigned char a; unsigned char b; } x, y;
x.a = 0;
y = x;
Run Code Online (Sandbox Code Playgroud)

C [N1570] 6.3.2.1 2说"如果左值指定了一个自动存储持续时间的对象,该对象可以用寄存器存储类声明(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明)在使用之前没有对它进行任何分配),行为是不确定的."

虽然已为某个成员x分配了一个值,但x尚未执行任何分配,并且尚未对其进行分配.因此,看起来6.3.2.1 2告诉我们xin 的行为y = x是未定义的.

但是,如果我们为每个成员分配了一个值x,那么x为了6.3.2.1 2的目的考虑未初始化似乎是不合理的.

(1)严格来说,标准中是否有任何内容导致6.3.2.1 2不适用于(未定义)上述代码?

(2)假设我们正在修改标准或确定对6.3.2.1的合理修改2,是否有理由偏好以下其中一项而不是其他?(a)6.3.2.1 2不适用于结构.(b)如果一个结构的至少一个成员被赋予了一个值,则该结构在6.3.2.1的目的下不是未初始化的.(c)如果一个结构的所有已命名的1个成员都被赋予了一个值,那么该结构是为6.3.2.1的目的而未初始化2.

脚注

1结构可能具有未命名的成员,因此并不总是可以为结构的每个成员分配值.(即使结构初始化,未命名的成员也具有不确定的值,每6.7.9 9.)

Ser*_*sta 8

我的观点是,它是未定义的行为,仅仅因为标准没有明确定义.从4一致性§2(强调我的):

......未定义的行为在本国际标准中以"未定义行为" 或"省略任何明确的行为定义 "的字样表示.

在N1570草案中进行了多次读取之后,我找不到任何使用部分初始化结构的行为的明确定义.一方面6.3.2.1§2说:

...如果左值指定了一个自动存储持续时间的对象,该对象可以使用寄存器存储类声明(从未使用过其地址),并且该对象未初始化(未使用初始化程序声明并且未对其进行任何赋值)在使用之前),行为是未定义的

所以这里x是自动的,从来没有被初始化(只有它的一个成员),并且很好地,它的地址从未被采用,所以我们可以认为它是明确的UB

另一方面,6.2.6.1§6说:

...结构或联合对象的值永远不是陷阱表示,即使结构或联合对象的成员的值可能是陷阱表示.

正如6.2.6.1§5刚刚定义了一个陷阱表示:

某些对象表示不需要表示对象类型的值.如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义的.如果这样的表示是由副作用产生的,该副作用通过左值表达式修改对象的全部或任何部分,该表达式表示a成员的0值和成员的未定义值b.没有字符类型,行为未定义.50)这种表示称为陷阱表示.

我们可以认为获取结构的值总是合法的,因为它不能成为陷阱表示

另外,对于我来说,如果设置结构的成员的值实际上使结构处于单元化状态是不明确的.

出于所有这些原因,我认为标准没有明确定义行为应该是什么,并且仅仅因为这个原因它是未定义的行为.


话虽这么说,我敢肯定,任何普通的编译器会接受它,并给y当前的表示x,这意味着为0值,a成员和相同的表示作为当前一个不确定的值x.bb成员.