考虑以下代码:
void func()
{
int p;
...
if (p > MAX) {
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
}
}
在这个片段s
中是在堆栈上。是否保证编译器将所有结构字段初始化为零?
考虑以下代码:
void func()
{
int p;
...
if (p > MAX) {
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
}
}
在这个片段s
中是在堆栈上。是否保证编译器将所有结构字段初始化为零?
不,恰恰相反。
由于s
是自动存储局部范围(即块范围)变量,除非显式初始化,否则内容是不确定的。
引用C11
,第 6.7.9 章
如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。[...]。
但是,如果您想对 an(y) 聚合类型的变量进行零初始化,您可以简单地使用如下初始化语句
aggregate-type variable = {0};
它使用同一章第 21 段中的以下属性,(强调我的)
如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。
如果变量(struct
或其他)被声明为函数或包含范围的本地变量(即具有自动存储持续时间),则它不会以任何方式初始化。您需要明确设置struct
.
如果您至少初始化一个结构体的一个字段而不是全部,那么其余字段将被初始化为与文件范围变量(即具有静态存储持续时间的变量)相同,这意味着NULL
指针类型和数字类型为 0。
从C 标准的第 6.7.9 节:
10 如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。如果具有静态或线程存储持续时间的对象未显式初始化,则:
— 如果它具有指针类型,则将其初始化为空指针;
— 如果它具有算术类型,则将其初始化为(正或无符号)零;
— 如果是聚合,则每个成员都根据这些规则(递归地)初始化,并且任何填充都被初始化为零位;
— 如果是联合,则根据这些规则(递归)初始化第一个命名成员,并将任何填充初始化为零位;
...
21 如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的剩余部分应隐式初始化与具有静态存储持续时间的对象相同。
不,它们根本不会被初始化。结构值将以放置结构的堆栈上的任何垃圾结束。
struct my_struct s;
...
/* here we access the contents 's' as '&s' */
这里你没有静态变量,你有一个自动变量,所以没有预初始化。
另一方面,如果您使用优化进行编译,则无法保证编译器存储此变量的位置,除非您检查汇编程序的输出,这不是由 C 语言定义的。