堆栈上的结构 - 字段已初始化?

时间:2017-10-25 15:04:57

标签: c struct initialization automatic-storage

请考虑以下代码:

void func()
{
   int p;
   ...
   if (p > MAX) {
       struct my_struct s;
       ...
       /* here we access the contents 's' as '&s' */
   }
}

在此代码段中,s位于堆栈中。是否保证编译器将所有结构字段初始化为零?

4 个答案:

答案 0 :(得分:4)

不,这恰恰相反。

由于s是一个自动存储本地作用域(即块作用域)变量,除非明确初始化,否则内容为不确定

引用C11,章节§6.7.9

  

如果没有显式初始化具有自动存储持续时间的对象,则其值为   不定。 [...]。

但是,如果要对(y)聚合类型的变量进行零初始化,则只需使用像

这样的初始化语句
aggregate-type variable = {0};

使用同一章第21段中的以下属性,(强调我的

  

如果括号括起的列表中的初始值设定项少于元素或成员   用于初始化已知数组的字符串文字中的聚合或更少字符   大小比数组中的元素大,聚合的其余部分应为   隐式初始化与具有静态存储持续时间的对象相同。

答案 1 :(得分:4)

如果变量(struct或其他)被声明为函数或包含范围的本地(即具有自动存储持续时间),则不会以任何方式初始化它。您需要在struct中明确设置字段。

如果初始化结构的至少一个字段但不是全部,则剩余字段将初始化为与文件范围变量(即具有静态存储持续时间的变量)相同,这意味着NULL用于指针类型和数字类型为0。

来自C standard的第6.7.9节:

  

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

     

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

     

- 如果它有算术类型,则初始化为(正数或无符号)   零;

     

- 如果是聚合,则会初始化每个成员   (递归地)根据这些规则,并初始化任何填充   为零位;

     

- 如果是联盟,则第一个命名成员是   根据这些规则初始化(递归),任何填充都是   初始化为零位;

     

...

     

21 如果括号括起的列表中的初始值设定项少于聚合的元素或成员,或者字符数少于   用于初始化已知大小的数组的字符串文字   是数组中的元素,聚合的其余部分应为   隐式初始化与具有静态存储的对象相同   持续时间。

答案 2 :(得分:2)

不,他们根本没有被初始化。结构值将以放置结构的堆栈中的任何垃圾结束。

答案 3 :(得分:0)

struct my_struct s;
       ...
       /* here we access the contents 's' as '&s' */

这里没有静态变量,你有一个自动变量,因此没有预先初始化。

另一方面,如果使用优化进行编译,则无法保证编译器存储此变量的位置,除非您检查汇编程序的输出(未由C语言定义)。