问题
I have gcc 5.2.1 on RHEL6 and RHEL7, and it looks like _GLIBCXX_USE_CXX11_ABI gets disabled. It's not working even if I manually run -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14
. This means I won't get small string optimization feature. For example, the output of following code always have 8 and 'micro not set'. For SSO, size of std::string should be at least 16 if we look at code bits/basic_string.h. Any workaround?
#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
}
回答1:
bugzilla.redhat has below reply
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).
回答2:
It would depend on your libstdc++
version, make sure your include/link/runtime paths are correct. Search your system for that macro and then use that instead, just make sure you link against the correct stdlib/abi libs.
If you do not have that, you can always build it yourself, however beware that if the rest of the programs you have use the old ABI, they will not work with your new libstdc++
.
Edit: Thinking about this, did you specify the correct -std=
flag to g++
? Have you tried -std=gnu11
? It could be as trivial as that. If not, then read on. Do not manually specify that define, you will break ABI compatibility with your libstdc++
leading to cascades of wonderful crashes. The only time you can specify things like that are when you're building the stdlib yourself.
Rest of this is a bit overkill, but it explains how to build and/or pick which stdlib you want to use.
I have a similar problem when using version 2 ABI of libc++
, where everything that links against it has to be rebuilt with the right headers and thus the right ABI (things like small string optimization being one of them).
For example, when building C++ objects I use the following flags to specify a location to a custom stdlib header path instead of using the OS provided one (I use Clang but the principle is similar):
-nostdinc++ -I/usr/local/sdk/llvm.6.0.1/include/c++/v1/
And then during the linking phase I use an $ORIGIN
relative runtime search path since on production machines the standard library is installed in in a more sane location, but you can specify a fixed one to whichever stdlib you want. You also want to make sure the linker can find the appropriate stdlib during static linking with -L
.
-Wl,-rpath,'$ORIGIN/../lib' -L/usr/local/sdk/llvm.6.0.1/lib
You will need to link against -lstdc++
and -lsupc++
(order is important if static linking), as long as you provide the correct library search path, the static linker should find them which are the GCC/GNU C++ stdlib and ABI support library.
Beware, if you replace your system libstdc+ with this any programs linked against old ABI layout will break if they're dynamically linked so be careful.
来源:https://stackoverflow.com/questions/50836145/glibcxx-use-cxx11-abi-disabled-on-rhel6-and-rhel7