C++ 链接符号决议 -- 自以为懂了,结果...

查看 265|回复 5
作者:xuelang   
在 C++ 中使用 Protobuf 诡异的字段丢失问题排查这篇文章中,分析过因为两个一样的 proto 文件,导致链接错了 pb ,最终反序列化的时候丢失了部分字段。当时也提到过符号决议的过程,不管是动态链接还是静态链接,实际用的都是靠前面的库的符号定义。本来以为对这里的理解很深入了,直到最近又遇见一个奇怪的“符号重定义”问题。
➜ tree
.
├── demoA
│   ├── libDemoA.a
│   ├── sum.cpp
│   ├── sum.h
│   └── sum.o
├── demoB
│   ├── libDemoB.a
│   ├── sum.cpp
│   ├── sum.h
│   └── sum.o
└── main.cpp
问题:
demoA/sum.h 和 demoB/sum.h 如果都是只有 sum 函数,那么无论哪个先链接,都不会有问题。
但是一旦里面有 class ,定义不一样,那么就会出错。
更多可以看这篇:
深入理解 C++ 链接符号决议:从符号重定义说起

SUM, 符号, Cpp, 链接

codehz   
没报错的情况是不是可以报告成连接器的 bug 呢,至少应该给个警告(
xuelang
OP
  
@codehz 不是 bug ,是 feature 的
codehz   
@xuelang 怎么就不是 bug 了,根据那啥 ODR 规则,就不能存在同名的符号,但具体到这个情况,倒是有可能被归类为无须诊断的非良构程序
不能因为恰好通过编译链接,能运行,它就突然变成良构的了
zmcity   
因为链接是通过函数签名选需要链接的产物(.o ),而没有把每个签名对应的函数单独提取出来。
你先链了 A ,就会把 A.o 链接到产物里,然后 A 中又没有 DemoB(int, int)的签名,所以会把 B.o 链上,就会 multiple definition 。
yolee599   
为啥你们写 C/C++ 那么多奇怪的问题,就是骚操作太多,我写 C 写了几年都没这么多屁事
您需要登录后才可以回帖 登录 | 立即注册

返回顶部