G++ and clang++ incompatibility with standard library when building shared libraries?

强颜欢笑 提交于 2019-12-25 06:37:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!