是否使用未分配所有成员的结构未定义? [英] Is using a structure without all members assigned undefined?

查看:19
本文介绍了是否使用未分配所有成员的结构未定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在块范围内考虑此代码:

Consider this code in block scope:

struct foo { unsigned char a; unsigned char b; } x, y;
x.a = 0;
y = x;

C [N1570] 6.3.2.1 2 说如果左值指定了一个自动存储持续时间的对象,该对象可以用 register 存储类声明(从未获取其地址),并且对象未初始化(未使用初始化程序声明且在使用前未对其进行赋值),行为未定义."

C [N1570] 6.3.2.1 2 says "If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined."

虽然x的一个成员已经赋值了,但是没有对x进行赋值,也没有取到它的地址.因此,似乎 6.3.2.1 2 告诉我们 y = xx 的行为是未定义的.

Although a member of x has been assigned a value, no assignment to x has been performed, and its address has not been taken. Thus, it appears 6.3.2.1 2 tells us the behavior of x in y = x is undefined.

然而,如果我们为 x 的每个成员分配了一个值,为了 6.3.2.1 2 的目的,将 x 视为未初始化似乎是不合理的.

However, if we had assigned a value to every member of x, it would seem unreasonable to consider x to be uninitialized for the purposes of 6.3.2.1 2.

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

(1) Is there anything in the standard which, strictly speaking, causes 6.3.2.1 2 not to apply to (make undefined) the code above?

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

(2) Supposing we were modifying the standard or determining a reasonable modification to 6.3.2.1 2, are there reasons to prefer one of the following over the others? (a) 6.3.2.1 2 does not apply to structures. (b) If at least one member of a structure has been assigned a value, the structure is not uninitialized for purposes of 6.3.2.1 2. (c) If all named1 members of a structure have been assigned a value, the structure is not uninitialized for purposes of 6.3.2.1 2.

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

1 Structures may have unnamed members, so it is not always possible to assign a value to every member of a structure. (Unnamed members have indeterminate value even if the structure is initialized, per 6.7.9 9.)

推荐答案

我的观点是它是未定义的行为,因为它没有被标准明确定义.来自 4 Conformance §2(强调我的):

My opinion is that it is undefined behaviour simply because it is not explicitly defined by the standard. From 4 Conformance §2 (emphasize mine) :

...否则未定义的行为在本国际标准中用未定义行为"一词表示或由省略任何明确的行为定义.

...Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior.

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

After many reads in N1570 draft I cannot find any explicit definition of behaviour for using a partially initialized struct. On one hand 6.3.2.1 §2 says:

...如果左值指定一个自动存储持续时间的对象,该对象可能已经使用 register 存储类声明(从未获取其地址),并且该对象未初始化(未使用初始化程序声明且未对其进行赋值)在使用之前执行),行为未定义

...If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined

所以这里 x 是自动的,从来没有被初始化(只有它的一个成员),而且承认它的地址永远不会被占用,所以我们可以认为它是明确的 UB

so here x is automatic, has never be initialized (only one of its members), and admitedly its address is never taken so we could think that it is explicitely UB

另一方面,6.2.6.1 §6 说:

On the other hand, 6.2.6.1 §6 says:

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

... The value of a structure or union object is never a trap representation, even though the value of a member of the structure or union object may be a trap representation.

因为 6.2.6.1 §5 刚刚定义了一个陷阱表示:

As 6.2.6.1 §5 has just defined a trap representation:

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

Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that means 0 value for a member and an undefined value for b member. does not have character type, the behavior is undefined.50) Such a representation is called a trap representation.

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

we could think that it is always legal to take the value of a struct because it cannot be a trap representation

此外,我不清楚设置结构体成员的值是否实际上使结构体处于统一化状态.

In addition, it is not clear for me if setting the value of a member of a struct actually leaves the struct in an unitialized state.

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

For all those reasons, I think that the standard does not clearly defines what the behaviour should be and simply for that reason it is undefined behaviour.

话虽如此,我很确定任何常见的编译器都会接受它,并且会为 y 提供 x 的当前表示,这意味着 a 的值为 0 成员以及与 xb 的当前表示相同的不确定值,用于 b 成员.

That being said I am pretty sure that any common compiler will accept it and will give y the current representation of x, that means 0 value for a member and an indeterminate value of same representation as the current one for x.b for the b member.

这篇关于是否使用未分配所有成员的结构未定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆