行爲

2015-11-26 68 views
1

test.h行爲

#ifndef TEST_H 
#define TEST_H 

int i; 

int i = 1; // why no redefinition error issued? 

#endif /* TEST_H */ 

test.c的

#include "test.h" 

int main() { 
    int x; 
    int x = i; // obviously, a redefinition 
    return 0; 
} 

我真的很好奇未初始化的全局變量的行爲一個頭文件。據我所知,無論是「int i」還是「int i」和「int i = 1」是i的有效定義,但實際上clang和gcc都不會爲這種情況發出錯誤。任何人都可以解釋細節嗎?

+3

'int I;'是_declaration_和_ **暫定** definition_,而不是「normal」_definition_。 – Olaf

+0

聞起來像未定義的行爲。 – Zimano

+0

這看起來很像描述而不是解釋。如果我們刪除尾部「int i = 1;」 i的定義,每次對i的訪問都可以看到編譯器自動分配的值0。你能詳細解釋一下嗎?謝謝〜 – bagwell

回答

1

這是試探性的定義,如解釋here

在翻譯單元的頂層(即預處理程序之後包含所有#include的源文件),每個C程序都是一系列聲明,聲明具有外部鏈接的函數和對象。這些聲明被稱爲外部聲明,因爲它們出現在任何函數之外。

暫定定義

暫定定義是一個外部聲明沒有初始化,並且或者沒有存儲類說明或與指定符靜態的。

暫定義是一個可能或可能不作爲定義的聲明。如果在同一翻譯單元中早或晚時發現實際的外部定義,那麼暫定義只是作爲聲明。

int i1 = 1;  // definition, external linkage 
int i1;   // tentative definition, acts as declaration because i1 is defined 
extern int i1; // declaration, refers to the earlier definition 

extern int i2 = 3; // definition, external linkage 
int i2;   // tentative definition, acts as declaration because i2 is defined 
extern int i2;  // declaration, refers to the external linkage definition 

如果在相同的翻譯單元沒有定義,則暫定定義作爲與初始化= 0(或者,對於數組類型,= {0})實際的定義。

int i3;  // tentative definition, external linkage 
int i3;  // tentative definition, external linkage 
extern int i3; // declaration, external linkage 
// in this translation unit, i3 is defined as if by "int i3 = 0;" 
+0

感謝您的鏈接! – bagwell