【发布时间】:2015-05-18 17:44:52
【问题描述】:
我有 2 个库:test.1 和 test.2。这两个库都包含一个全局 extern "C" void f(); 函数,具有不同的实现(只是一个 cout 用于测试)。
我做了以下测试:
测试 1 动态链接:
如果我在可执行文件的makefile中添加libtest.1.so,然后添加libtest.2.so,然后在main中调用f();,则会调用libtest.1.so->f()。
如果我更改 makefile 中的顺序,则会调用 libtest.2.so->f()
测试 2 静态链接:
静态库也是如此
测试 3 动态加载
由于库是手动加载的,所以一切都按预期工作。
我预计多个定义会出错,这显然没有发生。
此外,这并没有违反单一定义规则,因为情况不同。
这也不是一个依赖地狱(根本不与此相关),也不是任何链接惨败..
那么,这是什么?未定义的行为?未指定的行为?还是真的取决于链接顺序?
有没有办法轻松检测到这种情况?
相关问题:
dlopen vs linking overhead
What is the difference between dynamic linking and dynamic loading
Is there a downside to using -Bsymbolic-functions?
Why does the order in which libraries are linked sometimes cause errors in GCC?
linking two shared libraries with some of the same symbols
编辑我又做了两个测试,证实了这个 UB:
我在test.1 中添加了第二个函数void g() 而不是在test.2 中。
使用动态链接和 .so 库,同样的情况会发生 - f 以相同的方式调用,g 也是可执行的(如预期的那样)。
但是现在使用静态链接改变了事情:如果test.1 是之前 test.2,则没有错误,来自test.1 的两个函数都被调用。
但是当顺序改变时,会出现“多重定义”的错误。
很明显,“不需要诊断”(请参阅@MarkB 的回答),但“奇怪”的是有时会发生错误,有时 - 它不会。
无论如何,答案很清楚,并解释了上面的所有内容 - UB。
【问题讨论】:
-
/me 认为您应该检查此行为的标准是 ELF 标准,而不是 C++ 标准。
标签: c++ c static-linking dynamic-linking multiple-definition-error