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

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

问题描述

在代码块范围内考虑以下代码:

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符合§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:

...如果 左值表示一个自动存储持续时间的对象,该对象本来可以 用寄存器存储类声明(从未使用其地址),然后声明该对象 未初始化(未使用初始化程序进行声明,并且尚未对其进行赋值 使用之前执行),则行为未定义

...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

此外,对于我来说,尚不清楚是否设置结构成员的值是否实际上使该结构处于 unitialized 状态.

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.

话虽这么说,我很确定任何通用编译器都会接受它,并将给出x的当前表示形式,这意味着a成员的值为0,与当前表示形式相同的不确定值一个x.b代表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天全站免登陆