2

例如

union
{
    int n;
    void *p;
} u;

un或up的初始值是否等于0?

需要注意的是,NULL 指针不一定存储在全零位中。因此,即使 un 和 up 大小相同,

u.n == 0

不保证

u.p == 0

反之亦然。

(对不起我的英语不好)

4

4 回答 4

3

如果具有静态存储持续时间的对象未显式初始化,则:

— 如果它具有指针类型,则将其初始化为空指针;

— 如果它具有算术类型,则将其初始化为(正或无符号)零;

— 如果是聚合,则每个成员都根据这些规则(递归地)初始化;

— 如果是联合,则根据这些规则(递归地)初始化第一个命名成员。

因此u.n将被初始化为零并且u.p未确定。

编辑:对评论的回应

以上信息从 ISO/IEC 9899: 201x 6.7.9.10 复制

于 2013-09-13T14:09:43.337 回答
1

由于u是静态的,那么第一个成员将被初始化为zero,从C99 草案标准部分6.7.8 初始化10段:

如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。如果具有静态存储持续时间的对象未显式初始化,则

— 如果它具有指针类型,则将其初始化为空指针;

— 如果它具有算术类型,则将其初始化为(正或无符号)零;

— 如果是聚合,则每个成员都根据这些规则(递归地)初始化;

如果是 union,则根据这些规则(递归地)初始化第一个命名成员。

因为n是 aarithmetic type它将被初始化为zero. 的值p未指定,但实际上类型双关语通常由编译器支持,例如gcc 手册点此处用于类型双关语,我们可以在-fstrict-aliasing部分看到说:

从不同的工会成员那里阅读而不是最近写入的成员(称为“类型双关语”)的做法很常见。即使使用 -fstrict-aliasing,也允许使用类型双关语,前提是通过联合类型访问内存。

还值得注意的是,您may可以像这样初始化联合的任何成员:

union { int n; void *p; } u = { .p = NULL } ;
                              ^^^^^^^^^^^^^

我不确定是否所有编译器都支持这一点。

于 2013-09-13T14:14:57.990 回答
-1

我认为“全局变量”是指它在文件范围内。如果是这样,并且如果它被声明为“静态”,它将被初始化为全零位,例如因为它是在.BSS 中分配的。联合存储中的那些零位在您访问的任何成员的值方面意味着什么取决于它们的类型。在您的情况下, int 中的所有零位意味着它的值为零,而指针中的所有零位都使其为 NULL,即@Dukeling 在这里大放异彩。我不确定浮点数中的所有零位都会产生一个值为零的浮点数。

于 2013-09-13T14:19:54.510 回答
-1

这取决于您如何实例化变量本身。通常静态定义的变量被初始化为零。如果你 malloc 联合到一个指针,你可能会得到未初始化的内存。但是,如果您使用 calloc 为联合分配内存,则 calloc 将根据手册页将分配的内存初始化为零。

它还可能取决于您可能正在使用的任何库。当您调用它覆盖的 calloc 时,Google 的 perftools 库可能会将内存清零,也可能不会清零。

于 2013-09-13T14:46:01.647 回答