簡體   English   中英

沒有為多個定義生成編譯器警告

[英]Compiler warning not generated for multiple definitions

我面臨的問題是在兩個.c文件中定義了具有相同簽名的函數,並且沒有給出編譯時錯誤。 我已經在.h文件中包含了聲明,這兩個.c文件中都包含了聲明。

例如:

int add(int x, int y) { return x+y;}

在兩個.c文件(說Ac和Bc)中給出了相同的定義,並在一個包含在Ac和Bc中的.h文件中進行了聲明,但是為什么這沒有給出編譯時錯誤,或者如何使它們出現編譯錯誤?

連Linker都沒有給出任何錯誤,它看起來像是第一個定義

我正在使用GCC編譯器mingw

我發現了另一個模式。 如果我在頭文件中使用它

#ifndef H_H_
#define H_H_

鏈接器未給出警告警告,但如果我不使用此鏈接器,則將給出警告。

編譯器不會整體分析您的程序。 它一次只處理一個.c文件。 如果.h文件中的聲明與.c文件中的定義匹配,則就編譯器而言,一切都很好。

鏈接器將檢測到該函數已定義兩次,並將生成“重復符號”錯誤。

編譯器看到每個源文件彼此分開。 編譯器將頭文件的內容包含到Ac中,然后從AcAobj文件生成一個目標文件A.obj,其中將包含Ac中定義的變量和函數的符號。另一方面,編譯器將對Bc進行分開處理,而無需檢查Ac,或者其他源文件,內容。 首先將頭文件包含到Bc中,然后生成B.obj,其中還包含Bc中定義的變量和函數的符號

結果,由於編譯器未檢測到函數重復,因此在編譯時不會出現錯誤。 鏈接器工作是檢查符號一致性以及是否存在重復項。 鏈接器將獲取所有生成的目標文件,以生成可執行文件。 鏈接器必須為每個符號分配一個唯一的內存地址。 例如,在您的代碼中,如果確實有一個點(比如說在主要函數中)調用了Ac的函數,那么實際上這會轉換為對該函數所在的內存地址的跳轉。 現在,假設在可執行文件中是否存在兩個具有相同簽名的函數,並且每個符號具有不同的地址。 然后,處理器如何確定您打算在程序中確切調用哪個函數。 因此,如果鏈接器發現重復的符號,則將發出錯誤信號。

這種情況是不確定的行為,不需要診斷。

請查閱鏈接器的文檔,以查看它是否具有報告多個功能定義的選項。

正如@ Matt-McNabb所說:請查閱鏈接器文檔。

我唯一能想到的其他原因是鏈接程序二進制文件比較了兩個函數,發現它們是同義的,而忽略了一個。 您可以通過稍微更改代碼來進行檢查,例如通過“返回y + x”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM