e.g。
union
{
int n;
void *p;
} u;
u.n的初始值或u.p的初始值是否等于0?
应该注意,NULL指针不一定存储在全零位中。因此,即使u.n和u.p具有相同的大小,
u.n == 0
不保证
u.p == 0
反之亦然。
(抱歉我的英语不好)
答案 0 :(得分:3)
如果未明确初始化具有静态存储持续时间的对象,则:
- 如果它有指针类型,则将其初始化为空指针;
- 如果它有算术类型,则初始化为(正或无符号)零;
- 如果是聚合,则根据这些规则初始化(递归)每个成员;
- 如果是联合,则根据这些规则初始化(递归)第一个命名成员。
因此u.n
将被初始化为零,u.p
未确定。
编辑:回复评论
从ISO / IEC 9899:201x 6.7.9.10
复制的上述信息答案 1 :(得分:1)
由于u
是静态的,因此第一个成员将从C99 draft standard部分zero
初始化段初始化为6.7.8
10 :
如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。如果未明确初始化具有静态存储持续时间的对象,则:
- 如果它有指针类型,则将其初始化为空指针;
- 如果它有算术类型,则初始化为(正或无符号)零;
- 如果是聚合,则根据这些规则初始化(递归)每个成员;
- 如果是联盟,则根据这些规则初始化(递归)第一个命名成员。
由于n
是arithmetic type
,因此会将其初始化为zero
。 p
的值未指定,但实际上,编译器通常支持类型惩罚,例如gcc manual points here for Type-punning,我们可以在 -fstrict-aliasing 部分看到:< / p>
从不同的工会成员阅读的做法比最近写的那个(称为“打字式”)很常见。即使使用-fstrict-aliasing,只要通过union类型访问内存,就允许类型为punning。
值得注意的是,may
能够像这样初始化任何联盟成员:
union { int n; void *p; } u = { .p = NULL } ;
^^^^^^^^^^^^^
我不确定所有编译器是否都支持这一点。
答案 2 :(得分:-1)
我认为'全局变量'意味着它在文件范围内。如果是这样,并且如果它被声明为“静态”,它将被初始化为所有零位,例如因为它在.BSS中被分配。 联合存储中的这些零位意味着它所访问的成员的值取决于它们的类型。在你的情况下,int中的所有零位意味着它的值为零,并且指针中的所有零位使其为NULL,即@ Dukeling在这里爆炸。 我不确定float中的所有零位都会产生值为零的浮点数。
答案 3 :(得分:-1)
这取决于您如何实例化变量本身。通常,静态定义的变量初始化为零。如果你将联合malloc指向一个指针,你可能会得到未初始化的内存。但是,如果使用calloc为union分配内存,calloc将根据手册页将已分配的内存初始化为零。
它也可能取决于您可能正在使用的任何库。当您调用覆盖的calloc时,Google的perftools库可能会也可能不会将内存清零。