使用 clang 12 构建 c++20 模块时(它也使用 clang 10 复制)从模块中导出全局变量并在另一个编译单元中从同一个导出类声明全局变量会导致“`vtable for foo' 的多重定义”。
我的理解是可以使用单个 cppm 源创建 c++20 模块(clang 使用 cppm 作为模块),编译器将生成模块声明和它的定义。在这种情况下,clang++ 似乎确实生成了两次 vtable。
这是设置
foo.cppm:
export module foo;
export struct foo {
virtual void vf();
};
void foo::vf() {}
export foo module_foo; // variable, exported
主.cpp:
import foo;
foo main_foo;
int main() {
return 0;
}
构建主可执行文件的编译步骤:
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules --precompile foo.cppm -o foo.pcm
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules --compile foo.cppm -o foo.o
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules -fmodule-file=foo.pcm --compile main.cpp -o main.o
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules foo.o main.o -o main
导致 foo 类的重复 vtable 和类型信息:
/usr/bin/ld: main.o:(.rodata+0x20): multiple definition of `typeinfo for foo'; foo.o:(.rodata+0x20): first defined here
/usr/bin/ld: main.o:(.rodata+0x18): multiple definition of `typeinfo name for foo'; foo.o:(.rodata+0x18): first defined here
/usr/bin/ld: main.o:(.rodata+0x0): multiple definition of `vtable for foo'; foo.o:(.rodata+0x0): first defined here
这是一个 llvm 错误还是我做错了什么,我对模块应该如何工作感到困惑?