_GLIBCXX_USE_CXX11_ABI RHEL6 和 RHEL7 上禁用了吗?

_GLIBCXX_USE_CXX11_ABI disabled on RHEL6 and RHEL7?

本文关键字:USE GLIBCXX CXX11 ABI RHEL6 RHEL7      更新时间:2023-10-16

我在 RHEL5.2.1 和 RHEL7 上有 gcc 5.2.1,看起来_GLIBCXX_USE_CXX11_ABI被禁用了。即使我手动运行-D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14也不起作用.这意味着我不会获得小字符串优化功能。例如,以下代码的输出始终具有 8 和"微未设置"。对于SSO,如果我们查看代码位/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
}

bugzilla.redhat 有以下回复

雅各布·耶利内克 2018-02-19 06:08:00 EST

我们已经努力了,但不可能支持这一点,也不是 RHEL6 也不是 RHEL7,这就是它被强制禁用的原因。 它将 在 RHEL8 中工作(并且也是那里的默认(。

这取决于您的libstdc++版本,请确保您的包含/链接/运行时路径正确。在您的系统中搜索该宏,然后改用它,只需确保链接到正确的 stdlib/abi 库即可。

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


编辑:考虑到这一点,您是否指定了正确的-std=标志来g++?你试过-std=gnu11吗?它可以像这样微不足道。如果没有,请继续阅读。不要手动指定该定义,您将破坏与libstdc++的 ABI 兼容性,从而导致一系列精彩的崩溃。您唯一可以指定此类内容的时间是当您自己构建 stdlib 时。


其余部分有点矫枉过正,但它解释了如何构建和/或选择要使用的 stdlib。

在使用libc++的第 2 版 ABI 时,我遇到了类似的问题,其中链接到它的所有内容都必须使用正确的标头重建,从而使用正确的 ABI(例如小字符串优化就是其中之一(。

例如,在构建C++对象时,我使用以下标志来指定自定义 stdlib 标头路径的位置,而不是使用操作系统提供的位置(我使用 Clang,但原理相似(:

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

然后在链接阶段,我使用$ORIGIN相对运行时搜索路径,因为在生产机器上,标准库安装在更理智的位置,但您可以为所需的任何 stdlib 指定一个固定库。您还希望确保链接器可以在与-L的静态链接期间找到适当的 stdlib。

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

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

请注意,如果您将系统libstdc+替换为此系统,则与旧ABI布局链接的任何程序如果动态链接,则会中断,因此请小心。