Большинство изменений языка ABI, похоже, не вызовут проблем, но изменение соглашения о вызовах для пустых типов классов в 12 может?
Изменение соглашения о вызовах дляпустые классы могут вызвать проблемы на 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());
}
two.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
было передано с использованием регистров, проблем не будет.)