2012-11-14 179 views

回答

4

由於函數的定義都包含在鏈接的時間,但decalration或語法檢查可執行文件全部是在編譯時

做考慮一件事也當你調用任何功能和編譯器是無法找到的函數的聲明那麼它會產生警告implicit declaration of func()

要刪除此警告消息,我們提供了func的前向聲明,int func();,它編譯時沒有任何警告消息。

你覺得爲什麼會發生這種情況?發生這種情況是因爲編譯器沒有找到符號。根據語言的語法,編譯器完全可以免費進行代碼錯誤。

但最終可執行的建築是在鏈接時完成的,然後連接開始尋找的func()功能defition,如果發現則罰款,如果不..然後Linker error

could not have resolved external symbol _func()

注:任何外部符號(這個可以根據編譯器會發生變化)

:在鏈接時

海合會只編譯使用該得到解決- >它會生成test.o文件

然後嘗試將它連結,使可執行

gcc -Werror -o test test.o - >test可執行

2

該標準不說什麼時候應該報告錯誤 - 這是直到編譯器,但基本上這是因爲這是錯誤被捕獲時

首先,編譯器解析文件。很容易看出,在同一翻譯單元中是否多次定義了structclass,這只是一個錯誤,在翻譯單元之間可以有多個類別定義),因爲它處理該翻譯單元。

其次,它將目標文件鏈接在一起(鏈接)。現在只能說它是多次導出相同的符號,因爲那是每次都發生錯誤的時候。

+0

我想我明白了現在的差異,謝謝 – Maroun

2

編譯程序時,編譯器需要知道要使用的結構的確切定義。但是我們只需要知道只有在我們試圖鏈接程序時才能使用哪個確切的函數。

所以如果一個結構被定義了兩次,編譯器在編譯過程中會感到困惑,因此在編譯時會抱怨。

對於編譯期間的函數,您可以有多個定義,但只有在鏈接期間纔會出現混淆,因此它在連接期間發出抱怨。

1

你說的不一定是真的。

如果「內聯」的功能,在頁眉的定義和隨後寫出它在編譯單元的定義,你會得到一個錯誤

...already has a definition.

你指的是這樣的當兩個不同的編譯單元定義(或查看定義)同一個函數時,所以在任何單獨的編譯單元中都沒有編譯錯誤,它們的組合導致了鏈接錯誤。

順便說一句,這是關鍵字inline實際上有所不同的地方。對於標題中定義的非模板化函數,如果使用關鍵字inline,則表示在定義此函數時可以存在多個編譯單元。它實際上並不保證編譯器將內聯它。

+0

感謝您的解釋,現在很清楚:) – Maroun