4

我在 RHEL6 和 RHEL7 上有 gcc 5.2.1,它看起来像 _GLIBCXX_USE_CXX11_ABI 被禁用。即使我手动运行它也不起作用-D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14。这意味着我不会获得小字符串优化功能。例如,以下代码的输出总是有 8 和 'micro not set'。对于 SSO,如果我们查看 code 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

}
4

2 回答 2

4

bugzilla.redhat有以下回复

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

我们已经尽力了,但无论是在 RHEL6 还是在 RHEL7 上都无法支持此功能,这就是它被强制禁用的原因。它将在 RHEL8 中工作(并且也是那里的默认设置)。

于 2018-06-14T05:45:39.930 回答
-1

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

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


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


其余的内容有点矫枉过正,但它解释了如何构建和/或选择您要使用的标准库。

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

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

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

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

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

您需要链接-lstdc++-lsupc++(如果是静态链接,顺序很重要),只要您提供正确的库搜索路径,静态链接器就会找到它们,它们是 GCC/GNU C++ 标准库和 ABI 支持库。

当心,如果你用这个替换你的系统 libstdc+ 任何与旧 ABI 布局链接的程序,如果它们是动态链接的,那么它们会中断,所以要小心。

于 2018-06-13T13:54:27.410 回答