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

2023-09-19 16:09:34 +08:00
 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++ 链接符号决议:从符号重定义说起

1894 次点击
所在节点    C++
23 条回复
xuelang
2023-09-20 13:04:17 +08:00
@geelaw 嗯嗯,这样解释确实是,符号解析更适合这里的场景。
MaskRay
363 天前
ODR violation 参见 https://maskray.me/blog/2022-11-13-odr-violation-detection 我打算把这个检测工具写完……

> 还有一点,linux so 动态链接库里的符号可以是未决的,但是 dll 缺一个函数,都没办法生成。光是这点,微软就已经领先 100 年。

这个可以怪 ELF linkers 默认选得不好(-z undefs)。如果链接 DSO 时用-z defs 就不会未决了

https://maskray.me/blog/2021-06-13-dependency-related-linker-options#z-defs
xuelang
362 天前
@MaskRay 哇,之前看这块就搜到了大佬的博客,原来也在 v 站这里。你在 编译链接这里研究好深,写了好多文章,膜拜~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/975233

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX