如果我从this document正确理解,则不禁止将使用较新编译器构建的应用程序链接到具有较旧编译器的库构建。另外,我没有找到有关GCC 4.8和4.9之间ABI变化的任何信息。但是,这是一个导致崩溃的小例子(显然由于vptr
无效):
#ifndef LIB_48_H
#define LIB_48_H
struct FooBase { virtual void foo() = 0; };
struct FooDerived : FooBase { virtual void foo() override {} };
void boom();
#endif // LIB_48_H
#include "lib-48.h"
#include <memory>
void boom() {
auto x = std::make_shared<FooDerived>();
x->foo();
}
#include "lib-48.h"
#include <memory>
int main() {
std::make_shared<FooDerived>(); // Essential to reproduce
boom();
}
$ g++-4.8 -shared -fPIC -Wall -Wextra -O2 -std=c++11 lib-48.cpp -o liblib-48.so
$ g++-4.9 -std=c++11 -Wall -Wextra app-49.cpp -L. -llib-48 -Wl,-R'$ORIGIN' -o app-49
$ ./app-49
Segmentation fault (core dumped)
使用gcc 4.8.5(Ubuntu 4.8.5-2ubuntu1~14.04.1)和gcc版本4.9.4(Ubuntu 4.9.4-2ubuntu1~14.04.1)在x86_64 Ubuntu(14.04和16.04)上重现。< / p>
请注意,使用相同的编译器编译app和lib会使SIGSEGV消失。编译-O0
以及其他一些修改也是如此。
问题很简单:这是一个错误,还是我做错了什么?