C++类同名导致的ABI错误 - 可打印的版本 +- WeHack BBS (https://bbs.wehack.space) +-- 版块: 计算机技术 (https://bbs.wehack.space/forum-5.html) +--- 版块: 程序设计讨论区 (https://bbs.wehack.space/forum-14.html) +--- 主题: C++类同名导致的ABI错误 (/thread-341.html) |
C++类同名导致的ABI错误 - vimacs - 06-13-2022 最近发现GCC在对C++程序进行链接时优化的时候,如果在不同的目标文件出现了同名类,会给出一个 "type ‘...’ violates the C++ One Definition Rule [-Wodr]" 的警告。开始我以为不是什么问题,直到后来发现它的确导致了错误之后,才知道为什么会有这个警告。 如何发现此类问题:开 address sanitizer 编译项目,运行时报告错误,但 ASAN 不知道错误的类型,推测可能是 ABI 类错误。 可以导致这类错误的例子如下: 代码: // v1.cc 代码: // v2.cc 代码: // main.cc 先编译这几个文件为目标文件,然后链接: 引用:g++ -o main main.o v1.o v2.o 这时运行结果正常。 但是如果改为: 引用:g++ -o main main.o v2.o v1.o 这时程序会报告一个 stack smashing 后崩溃。 原因就在于 v1.o 和 v2.o 里面 std::vector<A> 的成员函数都编译为弱符号,链接的时候连接器会选择其中一个符号使用,但是实际上相同符号指向的是不同的实现代码,从而导致程序出错。 解决这类问题的方法也很简单,使用 namespace 就可以了。 |