C解决duplicate symbol

6 篇文章 0 订阅

—2022-07-15 补充—
再次看这个问题很奇怪, #include 'HeadFile.h" 不是很常见的引入头文件形式吗?
如常见的 #include<stdio.h>,多个文件 include 也没报错啊。
原因: include的文件,如果只是方法声明 ok。 但包含 方法定义,就报错。
(好比,甲乙丙都说 我要丁帮忙,那ok。 但甲要高个子丁, 乙要矮个子, 丙要中等个子丁。 那肯定报错,我们就一个丁)

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

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值