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只在文件内可见)

参考文档

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