4

其中一些可能是重复的,但我很抱歉。
假设我有这个struct

struct foo
{
    int a; 
    int b; 
    int c;
};

1.如果struct foo类型对象以具有自动存储持续时间且没有初始化器的方式声明,是否保证它的所有成员都将被强制初始化为零?

{
    // other stuff
    struct foo bar;
    // other stuff
}

2.如果struct foo类型对象以具有自动存储持续时间并带有一些初始化程序的方式声明,是否保证未显式初始化的成员将被强制初始化为零?

{
    // other stuff
    struct foo bar = {.a = 1}; 
    // other stuff
}

3.如果struct foo类型对象以具有自动存储持续时间的方式声明并使用复合文字表达式,是否保证未显式初始化的成员将被强制初始化为零?

{
    // other stuff
    func((struct foo){.a = 1});
    // other stuff
}

非常感谢任何 C 标准参考!谢谢!

4

2 回答 2

5

总结,TL;DR

储存期限说明:

  • 在函数内部声明的变量具有自动存储期限(包括函数的参数)。
  • 声明为static的变量或在文件范围(“全局”)的函数外部声明的变量具有静态存储持续时间。

结构(和数组)初始化说明:

  • 如果您未初始化任何成员并且结构具有自动存储持续时间,则不会初始化任何内容。
  • 如果您未初始化任何成员并且结构具有静态存储持续时间,则所有成员均为零初始化。
  • 如果您初始化任何成员,那么您未触及的成员将被初始化为零。

C标准的相关部分(C17 6.7.9 §10):

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

  • 如果是指针类型,则初始化为空指针;
  • 如果它具有算术类型,则将其初始化为(正或无符号)零;
  • 如果是聚合,则根据这些规则(递归)初始化每个成员,并将任何填充初始化为零位;

其中“artihmetic type”是普通变量(如 )的标准乱码int,而“aggregate”是数组和结构的标准乱码。

在同一章中进一步向下(C17 6.7.9 §19):

...所有未显式初始化的子对象都应隐式初始化,与具有静态存储持续时间的对象相同。


回答您的问题:

  1. 如果 struct foo 类型对象以具有自动存储持续时间且没有初始化程序的方式声明,是否可以保证它的所有成员都将被强制初始化为零?

不,不能保证;如上面引用的第一句所述,它们的值是不确定的。

  1. 如果 struct foo 类型对象以具有自动存储持续时间并带有一些初始化程序的方式声明,是否可以保证未显式初始化的成员将被强制初始化为零?

是的,根据上面引用的 C17 6.7.9 §19。

  1. 如果 struct foo 类型对象以具有自动存储持续时间的方式声明并使用复合文字表达式,是否可以保证未显式初始化的成员将被强制初始化为零?

是的,因为复合文字是数组或结构,它们遵循相同的初始化规则。

于 2018-09-06T13:34:45.360 回答
2

首先,具有自动存储功能的未初始化变量永远不会被初始化。来自 C11 标准(ISO/IEC 9899:2011 §6.7.9/10):

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

然后从此结构初始化参考

所有未显式初始化的成员都以与具有静态存储持续时间的对象相同的方式进行隐式初始化。

如果我们遵循“隐式初始化”链接,我们有:

具有静态和线程本地存储持续时间的对象初始化如下

  • ...
  • 整数类型的对象被初始化为无符号零
  • ...

所以回答你的问题:

  1. 不,没有进行初始化,因为您的代码中没有显式初始化(​​请参阅标准中的引用)
  2. 是的,因为这是一个结构初始化
  3. 是的,原因与 2 相同。

提供的链接参考了该标准。

于 2018-09-06T13:23:39.790 回答