最初的问题分布在来自不同项目的数十万个 LoC 中。它包含很多成分:内联汇编、虚拟继承、间接级别、不同的编译器和编译器选项。(这就像一部惊悚片。)我很难简化为这个 SSCCE:
// a.hpp
struct A {
int i;
~A() { asm("" : "=r"(i)); }
};
struct B : public virtual A { };
struct C : public B { };
struct D {
D(C);
};
// a.cpp
#include "a.hpp"
void f(C) {
}
D::D(C c) {
f(c);
}
// main.cpp
#include "a.hpp"
int main() {
C c;
D d(c);
}
使用这些命令行构建:
g++ -O3 -fPIC -c a.cpp
clang++ -O3 -fPIC -c main.cpp
clang++ -fuse-ld=gold main.o a.o -o main
链接器输出是:
a.o:a.cpp:function D::D(C) [clone .cold]: error: relocation refers to global symbol "construction vtable for B-in-C", which is defined in a discarded section
section group signature: "_ZTV1C"
prevailing definition is from main.o
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
我相信 gcc、clang 或 gold 都存在错误。我的问题是它在哪里?(我想这是黄金,但我想在报告错误之前确定。)
FWIW:正如我所说,所有的成分都很重要,例如,如果asm
删除了,问题就会消失。使问题消失的更显着的变化是:
- 对所有 TU 使用相同的编译器,(无论是 g++ 还是 clang++。)
- 与 ld 链接(即删除
-fuse-ld=gold
) - 编译
main.cpp
不带-O3
. - 编译
main.cpp
不带-fPIC
. - 在链接器命令行中交换
a.o
和。main.o