GCC和LLVM之间的兼容性

3

我正在开发一个跨平台的项目,在OS X上,其中一部分必须使用clang/llvm构建,因为它创建了一个Cocoa窗口,而项目的其余部分则使用GCC构建。这被编译成一个静态库,然后链接到主可执行文件中。例如:

//printnum.h
std::pair<uint32_t, uint32_t> printnum(int num);

//printnum.mm
#include "printnum.h"
#include <stdio.h>

std::pair<uint32_t, uint32_t> printnum(int num)
{
    printf("%d\n", num);
    //..... Objective C Code.....
}

//main.cpp
#include "printnum.h"

int main()
{
    printnum(0);
    return 0;
}

我正在使用CMake生成一个makefile。我尝试了几组不同的编译器标志-fPIC等,但是我打印出来的值是1835455280、1746993968、1648001840。这两个编译器不应该是二进制兼容的吗?如果我将函数设置为void,那么它就可以正常工作。


我不了解LLVM,但是对于C++,即使是不同的GCC主要版本也不总是二进制兼容的。不过我认为你需要回溯一段时间才会遇到这个问题。 - ams
1
听起来像是个bug,请在LLVM的Bugzilla上提交一个问题报告。 - Anton Korobeynikov
1个回答

1
不同的编译器使用不同的策略来按值返回结构。一种常见的技术是在内部重写此内容:
struct retval func(int a)

...像这样:

void func(struct retval* retval, int a)

然而,小型结构可以在寄存器中返回。在这种情况下,std::pair<int, int> 只有8个字节,这意味着它在这个上下文中被视为小型结构。

我怀疑的是一个编译器正在执行第一个操作,而另一个编译器正在执行后一个操作。这意味着它们不匹配。

这样做是否正确?我不知道。我知道clang的libstdc++与gcc的不兼容。但在您的环境中,两个编译器可能会看到相同的库(您可能需要验证此内容)。我的理解是,在编译器之间的C++二进制兼容性通常被认为在现实世界中不可能实现,尽管在理论上可能是可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接