c - 使用不同的结构对齐设置

标签 c visual-studio structure memory-alignment

混合 (Visual Studio) 设置了不同结构对齐选项的 C/C++ 项目有什么问题?我知道我显然可以在不同的项目中设置不同的选项,但这对输出库/应用程序的行为有影响吗?

假设我有一个库,其结构对齐设置为 1 字节,如果我有一个链接到该库但将结构对齐设置为默认值的应用程序,是否会有问题?如果应用程序不使用库的结构,会有什么不同吗?

感谢您对此的任何帮助!

最佳答案

结构布局由编译时生效的对齐规则决定。出于效率原因,结构成员的对齐方式使其在内存中的地址是 2、4、8 或有时更大值的倍数。

根据结构成员的大小和对齐要求,在结构成员之间插入额外的填充,并且可以在结构的末尾添加额外的填充,以允许结构数组保持此对齐对所有数组元素的成员有效。 malloc 保证返回一个为所有实际目的对齐的指针:

分配成功时返回的指针经过适当对齐,因此可以将其分配给指向具有基本对齐要求的任何类型对象的指针

这种行为有时可以通过编译器开关和/或编译指示来控制,这在 Visual C/C++ 中似乎是可能的。

结果对于所述选项将产生不同填充的结构很重要。访问结构成员的代码在处理共享数据的各种库和程序中是不同的,调用未定义的行为

因此强烈建议不要对不同编译代码段之间共享的数据结构使用不同的对齐选项。无论它们存在于不同的程序、动态库、静态链接的目标文件、用户或内核代码、设备驱动程序等中,结果都是相同的:具有潜在灾难性后果的未定义行为(就像任何 UB)。

它只对不兼容模块之间使用和共享的结构很重要,但随着时间的推移很难跟踪谁使用和谁不使用共享头文件中发布的结构定义。仅在本地使用且其定义不可见的结构不应该造成问题,但只要它们保持私有(private)就不会造成问题。

如果您使用编译时开关,所有 结构都会受到这些影响,包括 C 库中的标准定义,以及头文件中本地或全局定义的所有结构。标准包含文件可能有规定使它们免受此类差异的影响,但您自己的结构定义不会。

除非您确切知道为什么需要这样做,否则不要使用编译时开关来执行此操作。不要在源代码中执行此操作(通过 pragma、属性和其他不可移植的结构),除非您是真正的专家,可以完全控制数据的每次使用。

如果您关心结构打包,请重新排序 struct 成员并适本地选择它们的类型来实现您的目标。在极易出错的情况下更改编译器的打包规则。参见 http://www.catb.org/esr/structure-packing/进行完整的研究。

关于c - 使用不同的结构对齐设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29047694/

相关文章:

c++ - 结构尺寸定义

c - 在结构体数组内初始化结构体数组

c - 编译器语法中if then else的翻译

c - pthread_mutex_t 位于结构体内部并在访问时锁定该结构体

我们可以在 C 语言中将整数值转换为指针类型吗?

ios - WinObjC 的 AFNetworking

c - for循环声明匿名结构,clang编译失败

ios - 解析 Visual Studio 推送通知

javascript - 如何在asp.net中添加动态javascript警报框?

C 相同结构不同尺寸