2017-07-30 30 views
1
//File a.c 
void main() 
{ 
    test(); 
} 

//File b.c 
#include<stdio.h> 
void test() 
{ 
    printf("Hi, I am test."); 
} 

我使用「gcc a.c b.c」編譯此代碼。然後我運行'a.out',輸出結果是「你好,我正在測試」。我的問題是在a.c文件中沒有test()的聲明,爲什麼代碼要編譯?在沒有聲明的情況下在另一個文件中調用函數不會導致編譯錯誤

+0

這些連接? –

+1

您是否看到警告?當我在你的代碼中使用'gcc'時,我看到「隱式聲明'test'」的警告。 – lurker

+0

購買C教程書。那麼你會明白爲什麼。切勿關閉警告 –

回答

2

C語言中的函數是extern默認情況下,這意味着連接將能夠給一個函數從文件a連接到文件b即使沒有程序員編寫#includeextern

我的海灣合作委員會編譯它與這個警告:warning: implicit declaration of function...的含義,通過看test();編譯器猜測什麼test是,並繼續。如果您已經定義teststatic會失敗,因爲static櫃檯默認extern

一兩件事,我想你應該注意的是這implicit declaration也使得編譯器猜測test返回類型,並且它會認爲類型是int。這可能會導致問題。

1

代碼編譯,因爲這是C標準所要求的(至少在1999年之前)。支持在1999年標準中被刪除,儘管一些編譯器仍然支持它 - 儘管它們可以被配置爲在這種情況下發出警告(例如關於隱式聲明)。

具體而言,出於C89/90向預標準C的向後兼容性的考慮,代碼調用函數的嘗試隱式聲明該函數返回int並接受可變參數列表。

這是當編譯器正在通過交流轉換器

鏈接時會發生什麼,它會工作,因爲函數具有相同的名稱。

如果調用函數的方式(返回值的用法和參數類型的數量)與函數的定義方式相匹配,這在實踐中可行。如果沒有匹配,結果可能是未定義的行爲。例如,如果函數是用4個參數定義的並且使用全部4個,但調用者提供了3個,則行爲是未定義的。同樣,如果函數被定義爲返回double,但調用者認爲它返回int

實際上,最好在所有編譯單元被調用之前聲明所有函數(例如,通過包含一個頭文件)。這使得編譯器有機會檢查函數被調用的方式是否與其聲明匹配。

還要注意的是,在所有C標準中,main()返回int,而不是void。支持main()返回void是一個編譯器擴展。

相關問題