如果我有一个文件clang.cpp包含:
#include <map>
void myfunc() {
std::map<int, int> mymap;
const int x = 20;
myfoo[x] = 42;
}
和main.cpp包含:
void myfunc();
int main() { myfunc(); }
编译clang++ -g clang.cpp -shared -fPIC -o libclang.so -stdlib=libstdc++ -std=c++11
和clang++ -g main.cpp -L -Wl.,-rpath=. -lclang -lstdc++ -o a.out -stdlib=libstc++ -std=c++11
运行正常。
但是,如果我添加包含以下内容的gcc.cpp:
#include <tuple>
template std::pair<int const, int>::pair(std::piecewise_construct_t, std::tuple<int const&>, std::tuple<>);
然后使用g++ -g gcc.cp -shared -fPIC -o libgcc.so
将其编译到共享库,并将链接命令更改为clang++ -g main.cpp -L -Wl.,-rpath=. -lgcc -lclang -stdlib=libstdc++ -std=c++11 -o a.out
,然后运行./a.out
将分段错误。
我不知道该怎么做,因为在使用相同的c ++标准库时,clang和gcc应该是ABI兼容的。我的版本是clang的3.6.2,gcc的5.2.1,与ubuntu一起提供。
答案 0 :(得分:3)
鉴于
int f(std::tuple<const int &> t){
return std::get<0>(t);
}
Clang生成
f(std::tuple<int const&>): # @f(std::tuple<int const&>)
movl (%rdi), %eax
retq
而GCC生成
f(std::tuple<int const&>):
movq (%rdi), %rax
movl (%rax), %eax
ret
换句话说,Clang期望元组本身通过寄存器传递,而GCC期望地址在寄存器中传递(并且元组在堆栈上传递)。
混合搭配,你会得到“有趣”的结果。