c++ - 构建共享库时 G++ 和 clang++ 与标准库不兼容?

标签 c++ gcc clang compiler-bug

如果我有一个文件 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++11clang++ -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会出现segment fault。

我不知道该怎么做,因为在使用相同的 C++ 标准库时,clang 和 gcc 应该是 ABI 兼容的。我的版本是 3.6.2 for clang,5.2.1 for gcc,与 ubuntu 一起提供。

最佳答案

给定

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 期望地址在寄存器中传递(元组在堆栈中传递)。

混合搭配,你会得到“有趣”的结果。

关于c++ - 构建共享库时 G++ 和 clang++ 与标准库不兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35586332/

相关文章:

c++ - 我想创建一个无需创建对象即可调用函数的源文件

C++ 运算符重载不起作用

gcc - gcc -O2 对递归斐波那契函数做了什么?

c++ - 如何在 Linux 上延迟加载共享库

clang - -march = native使用Clang激活哪些标志?

c++ - 无论结果如何,支持除以零的最快整数除法是什么?

c++ - Eigen 中用户定义结构的数组

条件宏定义

c++ - 无法在 GCC 上编译此 Boost 算法示例

c++ - 为什么 Mac 上的 clang 会自动包含一些缺失的 header ?