我在RHEL6和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
}
答案 0 :(得分:3)
bugzilla.redhat有以下回复
Jakub Jelinek 2018-02-19 06:08:00 EST
我们已经努力了,但不可能支持这一点,也不可能 RHEL6也不在RHEL7上,这就是它被强制禁用的原因。它会 在RHEL8中工作(也是默认设置)。
答案 1 :(得分:-1)
这取决于您的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布局链接的程序如果动态链接都会中断,所以要小心。