Is it safe to link gcc 6, gcc 7, and gcc 8 objects?

血红的双手。 提交于 2019-12-03 05:50:49

问题


Is it safe to link C++17, C++14, and C++11 objects asks about linking objects compiled with different language standards, and Jonathan Wakely's excellent answer on that question explains the ABI stability promises that gcc/libstdc++ make to enusure that this works.

There's one more thing that can change between gcc versions though - the language ABI via -fabi-version. Let's say, for simplicity, I have three object files:

  • foo.o, compiled with gcc 6.5 c++14
  • bar.o, compiled with gcc 7.4 c++14
  • quux.o, compiled with gcc 8.3 c++17

All with the respective default language ABIs (i.e. 10, 11, and 13). Linking these objects together is safe from the library perspective per the linked answer. But are there things that could go wrong from a language ABI perspective? Is there anything I should be watching out for? 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?


回答1:


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?

The change of the calling convention for empty classes can cause an issue on x86-64. Here's an example:

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());
}

two.cpp:

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

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

Now, if you compile these with G++ 8 with differing ABIs of 11 and 12, for example:

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

the resulting a.out won't print the expected 42.

The reason is that the old ABI (11) reserves space for Empty() on the stack, but the new ABI (12) doesn't. So the address of foo will differ between the caller and the callee side.

(Note: I've included Foo::dummy so Foo gets passed using the stack instead of registers. If Foo was passed using registers, there would be no problem.)




回答2:


Most of them alter mangling in minor ways, which could cause some undefined references while linking, or just some code bloat due to identical source code producing two equivalent symbols with different names, so won't be merged by the linker.

the calling convention change for empty class types in 12 might?

Yes, definitely. If you have non-final parameters that are empty types then that affects the ABI for the function, and differences can lead to undefined behaviour (in practice, accessing junk on the stack, or parameters getting the wrong values).



来源:https://stackoverflow.com/questions/55730971/is-it-safe-to-link-gcc-6-gcc-7-and-gcc-8-objects

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