_GLIBCXX_USE_CXX11_ABI 在 RHEL6 和 RHEL7 上禁用?

_GLIBCXX_USE_CXX11_ABI disabled on RHEL6 and RHEL7?

我在 RHEL6 和 RHEL7 上安装了 gcc 5.2.1,看起来 _GLIBCXX_USE_CXX11_ABI 被禁用了。即使我手动 运行 -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14 它也不起作用。这意味着我不会获得小字符串优化功能。例如,下面代码的输出总是有 8 和 'micro not set'。对于 SSO,如果我们查看代码 bits/basic_string.h,std::string 的大小应该至少为 16。任何解决方法?

#include <string>
#include <iostream>

int main()
{
    std::cout << sizeof(std::string) << std::endl;

#if _GLIBCXX_USE_CXX11_ABI
    std::cout << "macro set" << std::endl;
#else
    std::cout << "macro not set" << std::endl;
#endif

}

这取决于您的 libstdc++ 版本,请确保您的 include/link/runtime 路径正确。在您的系统中搜索该宏,然后改用它,只需确保您 link 与正确的 stdlib/abi 库相对应。

如果您没有,您始终可以自己构建它,但请注意,如果您使用旧 ABI 的其余程序将无法与您的新 libstdc++ 一起使用。


编辑: 想一想,您是否为 g++ 指定了正确的 -std= 标志?你试过-std=gnu11了吗?它可能就这么微不足道。如果没有,请继续阅读。不要手动指定该定义,您将破坏 ABI 与您的 libstdc++ 的兼容性,从而导致一连串奇妙的崩溃。只有在您自己构建 stdlib 时才能指定此类内容。


其余部分有点矫枉过正,但它解释了如何构建 and/or 选择您要使用的标准库。

我在使用 libc++ 的第 2 版 ABI 时遇到了类似的问题,其中 link 反对它的所有内容都必须用正确的 header 重建,因此正确ABI(小字符串优化就是其中之一)。

例如,在构建 C++ 时 objects 我使用以下标志指定自定义 stdlib header 路径的位置,而不是使用 OS 提供的一个(我使用 Clang但原理类似):

-nostdinc++ -I/usr/local/sdk/llvm.6.0.1/include/c++/v1/

然后在 linking 阶段,我使用 $ORIGIN 相对运行时搜索路径,因为在生产机器上,标准库安装在一个更合理的位置,但您可以指定一个固定的一个到你想要的任何标准库。您还想确保 linker 可以在使用 -L 进行静态 linking 期间找到合适的标准库。

-Wl,-rpath,'$ORIGIN/../lib' -L/usr/local/sdk/llvm.6.0.1/lib

您将需要 link 反对 -lstdc++-lsupc++(如果静态 linking,顺序很重要),只要您提供正确的库搜索路径,静态 linker 应该找到它们,它们是 GCC/GNU C++ stdlib 和 ABI 支持库。

请注意,如果您将系统 libstdc+ 替换为此,任何针对旧 ABI 布局 linked 的程序如果是动态 linked 将会中断,所以要小心。

bugzilla.redhat 有以下回复

Jakub Jelinek 2018-02-19 06:08:00 EST

We've tried hard, but it is not possible to support this, neither on RHEL6 nor on RHEL7, which is why it is forcefully disabled. It will work in RHEL8 (and be the default there as well).