1. 程式人生 > >C++ 惱人的multiple definition of X連結錯誤

C++ 惱人的multiple definition of X連結錯誤

1. 錯誤原因

首先查了一下C&C++從原始碼編譯到可執行檔案的過程:

1)預處理將偽指令(巨集定義、條件編譯、和引用標頭檔案)和特殊符號進行處理

2)編譯過程通過詞法分析、語法分析等步驟生成彙編程式碼的過程,過程中還會進行優化

3)彙編過程將彙編程式碼翻譯為目標機器指令的過程(.o檔案,至少包含程式碼段和資料段)

4)連結程式將所有需要用到的目的碼(變數函式或其他庫檔案等)裝配到一個整體中(可分為靜態連結和動態連結)

前三個步驟總稱為編譯過程,第四個步驟為連結過程,這就是我們通常說的編譯+連結。

問題分析:預處理程式將include標頭檔案的內容包含進原始檔,這個過程完成後,標頭檔案就沒用了,然後就由編譯程式和彙編程式分別對預處理後的原始檔a.c, b.c, …生成目的碼.o檔案a.o, b.o, …,然後由連結程式裝配所有生成的.o檔案為可執行檔案,問題出在這裡,如果在標頭檔案中定義了變數(是定義不是宣告),並分別在a.c和b.c中進行了引用,編譯過程中這個變數的符號會同時包含在a.o和b.o中,導致連結失敗,原因是C語言規定“一個變數可以多次宣告但只能定義一次

”,解決辦法是在標頭檔案中加上#ifndef X條件編譯,使該變數只定義一次,但是這裡又有一個問題,該解決辦法只適用C而不適用C++,在C++中,即使在標頭檔案中加了#ifndef X,連結錯誤同樣會發生,原因是C++中#ifndef X的作用域僅在單個檔案中,因此只要在.h中定義了變數並在不同.cpp中進行引用,連結時都會報重定義錯誤,再說得直白點,a.cpp和b.cpp都引用了條件編譯的g.h,g.h的條件編譯只能分別保證在a.cpp和b.cpp中不出現重複定義,但在連結a.o和b.o的過程中就會發現重複定義。

 

解決方案:在申明和定義變數時新增static 字首即可。(針對我個人的具體情況)

詳細解決方案請參考附件連結。

 

參考連線:

https://www.cnblogs.com/edwardcmh/archive/2013/06/09/3129364.html