Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C结构对齐和跨编译器的可移植性_C_Windows_Portability - Fatal编程技术网

C结构对齐和跨编译器的可移植性

C结构对齐和跨编译器的可移植性,c,windows,portability,C,Windows,Portability,假设以下头文件对应于(例如)共享库。导出的函数采用指向此标头中定义的自定义结构的指针: // lib.h typedef struct { char c; double d; int i; } A; DLL_EXPORT void f(A* p); 如果共享库是使用一个编译器构建的,然后从使用另一个编译器构建的C代码中使用,那么它可能无法工作,因为内存对齐方式不同,正如所建议的那样。那么,有没有一种方法可以使我的结构定义在同一平台上的不同编译器之间进行移植 我对Windows平

假设以下头文件对应于(例如)共享库。导出的函数采用指向此标头中定义的自定义结构的指针:

// lib.h

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

DLL_EXPORT void f(A* p);
如果共享库是使用一个编译器构建的,然后从使用另一个编译器构建的C代码中使用,那么它可能无法工作,因为内存对齐方式不同,正如所建议的那样。那么,有没有一种方法可以使我的结构定义在同一平台上的不同编译器之间进行移植


我对Windows平台特别感兴趣(显然它没有一个定义良好的ABI),但我也很想了解其他平台。

不仅它没有得到保证,而且即使使用同一个编译器,由于构建中使用的编译器开关不同,也可能会有差异,或者,如果您使用同一编译器的不同版本和相同的开关(发生在我工作的嵌入式编译器中)

您需要确保结构的表示完全相同,使用开关、#pragmas,无论编译器提供什么

我的建议是——远离这一切。在函数中传递参数,而不是封装在结构中


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

TL;医生,实际上你应该没事

C标准没有定义这一点,但平台ABI通常有定义。也就是说,对于给定的CPU体系结构和操作系统,可以定义C如何映射到程序集,从而允许不同的编译器进行互操作

结构对齐不是平台ABI必须定义的唯一内容,您还可以使用函数调用约定之类的东西

C++使其更加复杂,ABI必须指定vtables、异常、名称混乱等

Windows上我认为有多个C++ abi依赖于编译器,但是C在编译器之间基本兼容。我可能错了,不是Windows专家

一些链接:

  • 什么是ABI
  • ABI必须定义的事情
  • 实例C++ C++ ABI规范< /L>
  • ABI是如何在Solaris上发展的

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

唯一确定的方法是查阅相关编译器的文档。然而,通常情况下,C结构布局(如您所说,位域除外)是由您所使用环境的ABI描述定义的,C编译器将倾向于遵循本机ABI。

否,除非有人向您保证。无重复。至少不是所选问题的一部分。这一个可以独立存在。任何包含“结构对齐”字样的问题是否自动与另一个问题重复,即使它与此无关?建议的重复实际上回答了问题“是否保证结构-内存对齐相同?”很好。这并不能保证,因为c标准允许每个编译器做出自己的选择。如果这里的主要问题是“如何确保我的结构定义在同一平台上的不同编译器之间是可移植的?”那么应该更加突出。你应该试着阅读所编译的文档。@ DMCKE,谢谢你的输入,我把问题再提了一点。谢谢你的努力,尽管我的问题根本不涉及C++。我知道ABI,这也是为什么我将问题标记为Windows专用,因为我从未听说过Windows上的ABI规范。@7vies:C也有ABI(想想不同的调用约定,cdecl、stdcall、fastcall)。只是对于C,不同的编译器通常是相同的(至少对于“正常”的调用约定是相同的),如果没有其他原因的话,就是为了匹配操作系统对系统调用的期望。使用C++,不同的编译器常常不同意同一个API,尤其是对于外部名称。@ MichaelBurr,作为一个旁注,维基百科说这些是x86约定,它们也在其他架构上使用吗?我知道C++的问题,这就是为什么我问如何使它在纯C中工作。调用约定有助于定义一个可移植的接口,但不能解决结构对齐的问题。(尽管它们可能相互影响;安腾ABI似乎影响了几个64位平台ABI)。我只是列举了x86的例子,说明了C是如何拥有ABI的。我认为Havoc的答案与你的答案差不多——C标准没有承诺,但平台要求会使它成为这样,因此在实践中,只要你不弄乱奇怪的类型,编译器之间的结构对齐方式(C++的POD structs)将是相同的(例如可能
long-long-double
)或滥用影响对齐的选项。