问题
with _GLIBCXX_USE_CXX11_ABI=0 std::function of GCC-4 is different of GCC-5 and follwing versions.
The following code show you the fact:
==> lib.cc <==
#include <functional>
std::function<int(const void*p)> holder;
int run_holder(const void *p)
{
return holder(p);
}
==> main.cc <==
#include <stdio.h>
#include <functional>
extern int run_holder(const void*p);
extern std::function<int(const void*p)> holder;
int foo(const void* p)
{
printf("p=%p\n", p);
return 0;
}
int main()
{
holder = foo;
foo((void*)0x12345678);
holder((void*)0x12345678);
run_holder((void*)0x12345678);
}
==> make.sh <==
#!/bin/bash
GCC4=/usr/bin/g++
GCCN="scl enable devtoolset-5 -- g++"
$GCC4 -std=c++11 -c -g lib.cc -shared -o libfoo.so &&
$GCCN -std=c++11 -L. -lfoo -g main.cc -o a.out &&
LD_LIBRARY_PATH=. ./a.out
expected result, something like:
p=0x12345678
p=0x12345678
p=0x12345678
actual result:
p=0x12345678
./make.sh: line 6: 973 Segmentation fault LD_LIBRARY_PATH=. ./a.out
The reason is the implementation of std::function changes without document.
gcc4: /usr/include/c++/4.8.2/functional:2430
typedef _Res (*_Invoker_type)(const _Any_data&, _ArgTypes...);
gcc5: /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/functional:2226 gcc8: /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/std_function.h:609
using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);
So I can not write a .so using std::function compiled by gcc4 and used by gcc5/6/7/8. There is no macro like _GLIBCXX_USE_CXX11_ABI can control the behavior.
回答1:
So I can not write a .so using std::function compiled by gcc4 and used by gcc5/6/7/8.
Correct. Neither Red Hat nor the GCC project has ever claimed that's possible, quite the opposite. C++11 support in GCC 4.x was incomplete and unstable, and subject to ABI changes and API changes. What you're trying to do was never supported.
I've explained this in more detail at https://stackoverflow.com/a/49119902/981959
The Developer Toolset documentation covers it too (emphasis mine):
"A compiler in C++11 or C++14 mode is only guaranteed to be compatible with another compiler in C++11 or C++14 mode if they are from the same release series (for example from Red Hat Developer Toolset 6.x).
...
"Using the C++14 language version is supported in Red Hat Developer Toolset when all C++ objects compiled with the respective flag have been built using Red Hat Developer Toolset 6 or later. Objects compiled by the system GCC in its default mode of C++98 are also compatible, but objects compiled with the system GCC in C++11 or C++14 mode are not compatible."
There is no macro like _GLIBCXX_USE_CXX11_ABI can control the behavior.
We do not provide macros to control things that are unsupported and cannot work.
If you want to use C++11 with a mix of GCC versions you need to use a release that has stable, non-experimental support for C++11. So not GCC 4.x.
来源:https://stackoverflow.com/questions/60291845/undocumented-abi-changes-of-stdfunction-between-gcc-4-and-gcc-5-6-7-8-9-how-t