с _GLIBCXX_USE_CXX11_ABI = 0 std :: function G CC -4 отличается от G CC -5 и следующих версий.
Следующий код показывает вам факт:
==> lib. cc <== </p>
#include <functional>
std::function<int(const void*p)> holder;
int run_holder(const void *p)
{
return holder(p);
}
==> main. cc <== </p>
#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
ожидаемый результат, что-то вроде:
p=0x12345678
p=0x12345678
p=0x12345678
фактический результат:
p=0x12345678
./make.sh: line 6: 973 Segmentation fault LD_LIBRARY_PATH=. ./a.out
Причина заключается в реализации изменений std :: function без документ.
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 / функционал: 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 используя std :: function, скомпилированную gcc4 и использованную gcc5 / 6/7/8. Нет такого макроса, как _GLIBCXX_USE_CXX11_ABI, который может управлять поведением.