这个问题是关于将未初始化的自动变量分配给另一个相同类型的变量的定义或其他方面。
Consider
typedef struct
{
int s1;
int s2;
} Foo;
typedef union
{
int u1;
Foo u2;
} Bar;
int main()
{
{
int a;
int b = a; // (1)
}
{
Foo a;
Foo b = a; // (2)
}
{
Bar a;
a.u1 = 0;
Bar b = a; // (3)
}
}
参考评论中main
:
(1) 未定义,因为a
未初始化。我知道的就这么多了。
但是(2)呢?结构体成员s1
and s2
未初始化。
此外,(3)呢?内存 u2.s2 未初始化,因此读取它是未定义的行为,不是吗?
(1) 和 (2) 中的行为未定义。
根据 C 标准,未初始化的具有自动存储持续时间的对象的值是不定(C 2011 [N1570] 6.7.9 10)。名义上,这意味着它有一定的价值,但我们在编写程序时并不知道它是什么。
然而,该标准还规定“如果左值指定一个具有自动存储持续时间的对象,该对象可以用register存储类(从未获取其地址),并且该对象未初始化(未使用初始值设定项声明,并且在使用之前未对其执行赋值),行为未定义”(6.3.2.1 2)。在您的示例代码中,地址a
从未被采用,也未初始化,并且在表达式中使用它是左值。因此,该行为是未定义的。
(这段 6.3.2.1 2 旨在适应能够检测未初始化寄存器的使用的处理器。尽管如此,C 标准中的规则适用于所有实现。)
(3) C 标准没有明确解决。尽管联合体的成员已被分配了值,因此出于 6.3.2.1 2 的目的并未未初始化,但在b = a
是联盟,而不是其成员。显然,我们直观的想法是,如果联合体的成员被赋值,那么联合体就有值。但是,我没有在 C 标准中看到这一点。
我们可以推断 6.3.2.1 2 并不打算将联合或结构视为未初始化,至少如果它的一部分已被赋值,因为:
结构可以具有未命名的成员,例如未命名的位字段。
根据 C 6.7.9 9,结构的未命名成员具有不确定的值,即使在(结构的)初始化之后也是如此。
如果 6.3.2.1 2 适用于并非每个成员都被赋值的结构,则b = a
如果a
是一个具有未命名成员的结构,并且具有自动存储期限。
这似乎不合理,也不是标准的初衷。
然而,这里还有一些回旋余地。该标准可以指定只有在结构已初始化或all其命名成员已被分配值。在这种情况下,(3) 将是未定义的,如果a
是一种结构,其中只有一个成员被分配了值。我认为工会不存在这种回旋余地;如果联合体的成员已被赋值,则只有合理地认为联合体未初始化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)