Undocumented ABI changes of std::function between GCC-4 and GCC-5/6/7/8/9, how to make a .so working with devtoolset-4/6/7/8/9?

社会主义新天地 提交于 2021-01-29 19:51:08

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!