首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未记录的性病ABI变化::GCC-4与GCC-5/6/7/8/9之间的功能,如何使.so与devtoolset-4/6/7/8/9协同工作?

未记录的性病ABI变化::GCC-4与GCC-5/6/7/8/9之间的功能,如何使.so与devtoolset-4/6/7/8/9协同工作?
EN

Stack Overflow用户
提问于 2020-02-19 01:44:22
回答 1查看 383关注 0票数 0

与_GLIBCXX_USE_CXX11_ABI=0的std::功能GCC-4是不同的GCC-5和折叠版本。

以下代码向您展示了这一事实:

==> lib.cc <==

代码语言:javascript
复制
#include <functional>

std::function<int(const void*p)> holder;

int run_holder(const void *p)
{
    return holder(p);
}

==> main.cc <==

代码语言:javascript
复制
#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 <==

代码语言:javascript
复制
#!/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

预期结果如下:

代码语言:javascript
复制
p=0x12345678
p=0x12345678
p=0x12345678

实际结果:

代码语言:javascript
复制
p=0x12345678
./make.sh: line 6:   973 Segmentation fault      LD_LIBRARY_PATH=. ./a.out

原因是没有文档的std::function的实现。

gcc4: /usr/include/c++/4.8.2/Functional2430

代码语言:javascript
复制
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

代码语言:javascript
复制
using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);

因此,我不能用.so编写gcc4编译的、由gcc5 5/6/7/8编译的函数。没有像_GLIBCXX_USE_CXX11_ABI这样的宏可以控制行为。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-24 10:54:27

,所以我不能使用std::函数编写.so,它由gcc4编译,由gcc5/6/7/8使用。

对,是这样。无论是红帽还是GCC项目都没有宣称这是可能的,恰恰相反。GCC 4.x中的C++11支持是不完整和不稳定的,受ABI变化和API变化的影响。你想做的事从来没有得到支持。

我已经在https://stackoverflow.com/a/49119902/981959上更详细地解释了这一点

开发人员工具集文档也涵盖了它(重点是我):

“C++11或C++14模式下的编译器只有在来自同一版本系列(例如6.x)的C++11或C++14模式下才能与另一个编译器兼容。

..。

“红帽开发人员工具集支持使用C++14语言版本,当使用相应标志编译的所有C++对象都已使用6或更高版本生成时。系统GCC在默认模式C++98中编译的对象也是兼容的,但是用C++11或C++14模式编译的系统GCC编译的对象不兼容。__。”

没有像_GLIBCXX_USE_CXX11_ABI这样的宏可以控制行为。

我们不提供宏来控制不受支持和无法工作的东西。

如果您想使用C++11和GCC版本的混合版本,您需要使用一个对C++11具有稳定的、非实验性支持的版本,而不是GCC 4.x。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60291845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档