gpt4 book ai didi

c++ - 链接 gcc 6、gcc 7 和 gcc 8 对象是否安全?

转载 作者:IT老高 更新时间:2023-10-28 22:14:21 26 4
gpt4 key购买 nike

Is it safe to link C++17, C++14, and C++11 objects询问有关链接使用不同语言标准编译的对象的问题,Jonathan Wakely 对该问题的出色回答解释了 gcc/libstdc++ 为确保其有效而做出的 ABI 稳定性 promise 。

还有一件事可以在 gcc 版本之间改变 - 通过 -fabi-version 的语言 ABI .假设,为简单起见,我有三个目标文件:

  • foo.o,用 gcc 6.5 c++14 编译
  • bar.o,用gcc 7.4 c++14编译
  • quux.o,用gcc 8.3 c++17编译

全部使用各自的默认语言 ABI(即 10、11 和 13)。根据链接的答案,从库的角度来看,将这些对象链接在一起是安全的。但是从语言 ABI 的角度来看,有没有可能出错的地方?有什么我应该注意的吗?大多数语言 ABI 更改似乎不会引起问题,但是 12 中空类类型的调用约定更改可能会?

最佳答案

Most of the language ABI changes seem like they wouldn't cause issues, but the calling convention change for empty class types in 12 might?

更改空类的调用约定可能会导致 x86-64 出现问题。这是一个例子:

def.hpp:

struct Empty { };

struct Foo {
char dummy[16];
int a;

Foo() : a(42) { }
};

void fn(Empty, Foo);

one.cpp:

#include "def.hpp"

int main() {
fn(Empty(), Foo());
}

两个.cpp:

#include <stdio.h>
#include "def.hpp"

void fn(Empty e, Foo foo) {
printf("%d\n", foo.a);
}

现在,如果您使用 G++ 8 编译它们,并且 ABI 为 11 和 12,例如:

g++ -c -fabi-version=11 one.cpp
g++ -c -fabi-version=12 two.cpp
g++ one.o two.o

生成的 a.out 不会打印预期的 42

原因是旧的 ABI (11) 在堆栈上为 Empty() 保留空间,而新的 ABI (12) 没有。所以 foo 的地址在调用方和被调用方之间会有所不同。

(注意:我已经包含了 Foo::dummy 所以 Foo 使用堆栈而不是寄存器来传递。如果 Foo 被传递使用寄存器,不会有问题。)

关于c++ - 链接 gcc 6、gcc 7 和 gcc 8 对象是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55730971/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com