问题
If I have a file clang.cpp containing:
#include <map>
void myfunc() {
std::map<int, int> mymap;
const int x = 20;
myfoo[x] = 42;
}
and main.cpp containing:
void myfunc();
int main() { myfunc(); }
compiling clang++ -g clang.cpp -shared -fPIC -o libclang.so -stdlib=libstdc++ -std=c++11
and clang++ -g main.cpp -L -Wl.,-rpath=. -lclang -lstdc++ -o a.out -stdlib=libstc++ -std=c++11
will run fine.
However, if I add gcc.cpp containing:
#include <tuple>
template std::pair<int const, int>::pair(std::piecewise_construct_t, std::tuple<int const&>, std::tuple<>);
then also compile that to a shared library using g++ -g gcc.cp -shared -fPIC -o libgcc.so
and change the linking command to clang++ -g main.cpp -L -Wl.,-rpath=. -lgcc -lclang -stdlib=libstdc++ -std=c++11 -o a.out
, then running ./a.out
will segment fault.
I don't know what to make of this, since clang and gcc are supposed to be ABI compatible when using the same c++ standard library. My versions are 3.6.2 for clang, 5.2.1 for gcc, as shipped with ubuntu.
回答1:
Given
int f(std::tuple<const int &> t){
return std::get<0>(t);
}
Clang generates
f(std::tuple<int const&>): # @f(std::tuple<int const&>)
movl (%rdi), %eax
retq
while GCC generates
f(std::tuple<int const&>):
movq (%rdi), %rax
movl (%rax), %eax
ret
In other words, Clang is expecting the tuple itself to be passed by register, while GCC is expecting the address to be passed in register (and the tuple passed on the stack).
Mix and match and you get "fun" results.
来源:https://stackoverflow.com/questions/35586332/g-and-clang-incompatibility-with-standard-library-when-building-shared-libra