2016-03-03 127 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未被初始化。儘管你引用輸出程序集可以減少你的情況。