C解決duplicate symbol

Context

  1. 在HeaderFile.h頭文件了聲明一個 LOG() 方法
    void LOG(std::string s)
    {
     std::cout << s << std::endl;
    }
    
  2. 在SourceFile1.cpp裏 #include “HeaderFile.h”
  3. 在SourceFile2.cpp裏 #include “HeaderFile.h”

編譯報錯, a方法 duplicate symbol

實際報錯的log

上文的Context只是說明關係,swapElement就等於上文的a方法, MergeSort.cpp TestSort.cpp等價於SourFile1.cpp、SourceFile2.cpp

 clang++ MergeSort.cpp TestSort.cpp -o testExecute
duplicate symbol __Z11swapElementPiii in:
    /var/folders/wv/16gvb9rd4v540qx_6vry7vqh0000gn/T/MergeSort-dd8696.o
    /var/folders/wv/16gvb9rd4v540qx_6vry7vqh0000gn/T/TestSort-0defcb.o

原因

  • C++,方法不能被重複聲明。
  • 編譯階段:#include “HeaderFile.h”,等於複製 HeaderFile.h 文件內容到 #include的位置。
  • 編譯輸出:每個cpp文件被編譯成.o文件,所以MergeSort.o,TestSort.o文件內,都copy了HeaderFile.h內的內容(即方法聲明)
  • 鏈接(Link)階段:鏈接每個.o文件成爲最終的 可執行文件。鏈接MergeSort.o,TestSort.o,出現兩個方法聲明,異常報錯 duplicate symbol

3種解決方法:

源碼文件裏,方法名稱 爲symbol(符號),相對概念是 內存地址,如LOG方法在 內存中的地址是什麼。

消除symbol

  1. 將method聲明爲inline。inline 方法的方法體,會被直接copy到 方法調用的地方。(也就是 鏈接階段是 沒有這個方法的)
    inline void LOG(std::string s)
    {
     std::cout << s << std::endl;
    }
    
  2. 採用宏定義#define LOG(s) (std::cout << s << std::endl),相當於不是方法了,就是文本替換了。

可見性

只在單個.o文件內可見
3. 將方法聲明爲static(表示方法不能被share,生成的symbol只在文件內可見)

參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章