2012-11-29 186 views
16

從此延伸question這是什麼類型的聲明?

我很難理解此代碼。

struct foo myfoo; // --> Is it forward declaration or object creation. ? 

struct foo 
{ 
int a; 
}; 

int main() 
{ 

return 0; 
} 

在代碼中標記爲箭頭-->它是前向聲明還是對象創建。 ?

如果是向前聲明又是什麼struct foo;叫什麼?如果它是對象創建或實例化,那麼它如何在struct定義之前創建對象。

gcc編譯它工作正常,但其他的編譯器會發出錯誤。

gcc -Werror -Wall tst.c -o tst 

對此行爲的任何建議或解釋gcc?我無法找到任何記錄。

+0

我沒有得到一個機會,看看C99的標準,所以我仍然不知道,如果是在某處指定+1。 – iabdalkader

+0

@melpomene:我同意 – Omkant

+0

@melpomene,或者一個功能?看起來好像理解結構是在稍後的同一個文件中定義的。 – Shahbaz

回答

16

貌似的myfoo暫定定義,因爲設置了結構的定義,你沒有錯誤。

clang提供了一個全面的診斷,當類型在未定義。

[email protected]:~$ cat tst.c 
struct foo myfoo; 

//struct foo{ 
// int x ; 
//} ; 

int main() 
{ 
} 
[email protected]:~$ clang tst.c 
tst.c:1:12: error: tentative definition has type 'struct foo' that is never 
     completed 
struct foo myfoo; 

我不認爲它的gcc bug,clang以及comeau online正在編譯代碼。

$ 6.9.2/2

爲具有文件作用域沒有初始化的對象的標識符的聲明,和 沒有存儲類說明或與存儲類說明靜態的,構成了一個 暫定義。如果翻譯單元包含一個 標識符的一個或多個試探性的定義,和翻譯單元包含該標識符的外部定義,然後 行爲是完全一樣,如果翻譯單元包含 標識符的文件範圍內聲明,與複合型,作爲翻譯單元的結束,有一個初始化 等於0


+4

好抓,C99 6.9.2/2。這是一個棘手的問題(當你習慣了C++)。 – netcoder

+0

標準在他們的例子中沒有提及struct(在C11中都沒有),這很有趣。 – Shahbaz

-2
struct foo myfoo; 

即稱爲myfoofoo類型的C變量的定義。 C要求您在struct變量聲明前明確聲明struct

現在,您的代碼不應該編譯,因爲編譯器不知道在您定義的myfoo的位置,foo的外觀類型。編譯器應該抱怨foo是不完整的類型。

編輯:

廢料的是,這將被稱爲暫定定義

+5

我不認爲你完全閱讀這個問題。 – Shahbaz

+0

在第6.9.2/2節中,暫定的定義最終「以複合類型作爲翻譯單元的末尾」,我相信這就是我們在問題中的含義。 – Mat

+0

什麼「兼容模式」?暫定義在C標準中有描述。 – Mat