2012-04-24 28 views
9

假设以下头文件对应于(例如)共享库。导出的函数需要一个指针在此头中定义的自定义结构:C编译器之间的结构对齐和可移植性

// lib.h 

typedef struct { 
    char c; 
    double d; 
    int i; 
} A; 

DLL_EXPORT void f(A* p); 

如果共享库使用一个编译器构建,然后从与另一个编译器构建的C代码用它可能不是因为不同的工作内存对齐,如Memory alignment in C-structs建议。那么,有没有办法让我的结构定义可以跨同一平台上的不同编译器使用?

我特别感兴趣的是Windows平台(显然它没有明确定义的ABI),但也很想了解其他平台。

+3

不,除非有人向你保证。 – 2012-04-24 12:50:49

+3

没有重复。至少不是所选问题。这个可以独立运作。 – 2012-04-24 13:05:34

+1

包含单词“struct alignment”的任何问题是否与其他问题的副本自动重复,即使与该问题无关? – 2012-04-24 14:28:36

回答

11

TL; DR在实践中你应该没问题。

C标准没有定义这个,但是平台ABI通常会这样做。也就是说,对于给定的CPU架构和操作系统,可以定义C映射到汇编的定义,以允许不同的编译器进行互操作。

结构对齐不是平台ABI必须定义的唯一东西,你也有函数调用约定和类似的东西。

C++使它更加复杂和ABI必须指定虚函数表,异常,名字改编等

在Windows上,我认为多C++的ABI取决于编译器也有,但C是跨编译器大多兼容。我可能是错的,不是Windows专家。

一些链接:

但无论如何,底线是,你正在寻找一个在您的保证平台/编译器ABI规范,而不是C标准。

+0

感谢您的努力,尽管我的问题根本不涉及C++。我知道ABI,这也是为什么我标记Windows特有的问题,因为我从来没有听说过Windows上的ABI规范。 – 2012-04-24 14:26:02

+0

@ 7vies:C也有一个ABI(想想不同的调用约定,cdecl,stdcall,fastcall)。只是对于C来说,不同的编译器通常是相同的(至少对于'普通'调用约定),如果没有其他理由而不是匹配OS期望的系统调用。对于C++,不同编译器经常*不同意相同的API,尤其是对于外部名称。 – 2012-04-24 14:42:38

+0

@MichaelBurr,作为一个便笺,维基百科表示这些是_x86_约定,它们是否也用于其他体系结构?我知道C++的问题,这就是为什么我要问如何使它在纯C中工作。调用约定有助于定义一个可移植的接口,但不能解决我在结构对齐方面的问题。 – 2012-04-25 13:53:37

1

不仅如此,即使您使用相同的编译器,由于构建中使用不同的编译器开关,或者如果您使用相同编译器和相同开关的不同版本(可能发生在一个我编写的嵌入式编译器)。

无论编译器为您提供什么,您都需要确保结构完全相同,使用开关,#pragmas。

我的建议 - 保持完全的方式。在函数中传递参数,而不是包装在结构中。

即使在这种简单的形式下,如果您处理两个编译器,它也不是微不足道的。例如,您需要确保int具有相同的字节数。另外调用conevntion - 参数顺序 - 从左到右或从右到左 - 可以在编译器之间有所不同。

3

确切知道的唯一方法是查阅相关编译器的文档。但是,通常情况下,C结构布局(除非如您所说,位字段除外)由您所用环境的ABI描述定义,而C编译器则倾向于遵循本地ABI。