2016-03-03 125 views
0

我正在验证结构成员初始化。编译器是gcc 4.8.5和代码是这样的:非显式初始化成员在其成员初始化的结构中始终为0?

#include <stdio.h> 

typedef struct 
{ 
     int m1; 
     int m2; 
} A; 

int main(void) { 
     A a; 
     A b = {.m1 =1}; 
     A c = {1}; 

     printf("%d, %d\n", a.m1, a.m2); 
     printf("%d, %d\n", b.m1, b.m2); 
     printf("%d, %d\n", c.m1, c.m2); 
     return 0; 
} 

执行它的结果是:

-1498088800, 32765 
1, 0 
1, 0 

并且该组件的代码是:

0x0000000000400530 <+0>:  push %rbp 
0x0000000000400531 <+1>:  mov %rsp,%rbp 
0x0000000000400534 <+4>:  sub $0x30,%rsp 
0x0000000000400538 <+8>:  movq $0x0,-0x20(%rbp) 
0x0000000000400540 <+16>: movl $0x1,-0x20(%rbp) 
0x0000000000400547 <+23>: movq $0x0,-0x30(%rbp) 
0x000000000040054f <+31>: movl $0x1,-0x30(%rbp) 
0x0000000000400556 <+38>: mov -0xc(%rbp),%edx 
0x0000000000400559 <+41>: mov -0x10(%rbp),%eax 
0x000000000040055c <+44>: mov %eax,%esi 
0x000000000040055e <+46>: mov $0x400640,%edi 
0x0000000000400563 <+51>: mov $0x0,%eax 
0x0000000000400568 <+56>: callq 0x400410 <[email protected]> 

从汇编代码:

0x0000000000400538 <+8>:  movq $0x0,-0x20(%rbp) 
0x0000000000400540 <+16>: movl $0x1,-0x20(%rbp) 
0x0000000000400547 <+23>: movq $0x0,-0x30(%rbp) 
0x000000000040054f <+31>: movl $0x1,-0x30(%rbp) 

我可以看到,如果我初始化结构的部分成员,其他成员默认设置为0。这是否符合C规范?还是只依赖于编译器?

+0

减一?我根本不明白这一点。 – Bathsheba

+0

http://stackoverflow.com/questions/10828294/c-and-c-partial-initialization-of-automatic-structure/10828333#10828333的可能的复制 –

回答

4

他们granteed为零。

报价从N1256 6.7.8初始化

10如果具有自动存储持续时间的对象没有被明确初始化,它的值是 不确定的。如果具有静态存储持续时间的对象没有被明确初始化,然后 :
- 如果它有指针类型,它被初始化为空指针;
- 如果它有算术类型,则它初始化为(正或无符号)零;
- 如果它是一个聚合,每个成员根据这些规则初始化(递归);
- 如果它是联合,第一个命名构件(递归地)根据这些规则 初始化。

21如果在一个大括号内的列表更少初始化比有元件或部件的集合体 ,或在使用除了有数组中的元素来初始化已知 大小的数组文本字符串更少的字符,剩余的聚合应该是 隐含地被初始化与具有静态存储持续时间的对象相同。

0

如果使用大括号初始化只有部分初始化结构,然后其余的是在完全相同的方式设置,因为他们是,如果结构实例有静态存储时间。

请注意,printf("%d, %d\n", a.m1, a.m2);的行为是未定义由于a未被初始化。尽管你引用输出程序集可以减少你的情况。