请考虑以下代码:
void func()
{
int p;
...
if (p > MAX) {
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
}
}
在此代码段中,s
位于堆栈中。是否保证编译器将所有结构字段初始化为零?
答案 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语言定义)。