具有不同结构对齐选项的混合(Visual Studio)C / C ++项目有哪些问题?我知道我显然可以在不同的项目中以不同的方式设置选项,但是这会对输出库/应用程序的行为产生影响吗?
假设我有一个库,结构对齐设置为1字节,如果我有一个链接到库的应用程序但是结构对齐设置为默认值会有问题吗?如果应用程序不使用库的结构会有所不同吗?
感谢您对此提供任何帮助!
答案 0 :(得分:0)
结构布局由编译时影响的对齐规则决定。出于效率原因,结构成员的对齐方式是使它们的地址在存储器中的倍数为2,4,8或有时更大。
根据结构构件的大小和对齐要求插入结构构件之间的额外填充,并且可以在结构的末尾添加额外的填充,以允许结构阵列保持此对齐对所有阵列元素的成员有效。 malloc
保证返回一个指针,用于所有实际目的:
如果分配成功,则返回的指针被适当地对齐,以便可以将其指定给指向具有基本对齐要求的任何类型对象的指针。
有时可以通过编译器开关和/或编译指示来控制此行为,这似乎可以通过Visual C / C ++实现。
结果对于所述选项将产生不同填充的结构很重要。访问结构成员的代码在处理共享数据的各种库和程序中有所不同,调用未定义的行为。
因此强烈建议不要对不同编译代码之间共享的数据结构使用不同的对齐选项。无论它们是否存在于不同的程序,动态库,静态链接的目标文件,用户或内核代码,设备驱动程序等,结果都是相同的:具有潜在灾难性后果的未定义行为(如任何UB)。
仅对不兼容模块之间使用和共享的结构很重要,但是很难跟踪谁使用谁以及谁不使用共享头文件中发布的结构定义。仅在本地使用且其定义不可见的结构不应构成问题,但只有在它们保持私有的情况下才会存在问题。
我使用编译时开关,所有结构都会受到这些结构的影响,包括C库中的标准定义,以及头文件中本地或全局定义的所有结构。标准包含文件可能有条款使它们免受这些差异的影响,但您自己的结构定义不会。
除非您确切知道为什么需要这样做,否则不要使用编译时开关。不要在源代码中执行此操作(通过编译指示,属性和其他非可移植结构),除非您是真正的专家,可以完全控制数据的每次使用。
如果您关注结构包装,请重新排序struct
成员并适当选择其类型以实现目标。在高度容易出错中更改编译器的打包规则。有关完整的研究,请参阅http://www.catb.org/esr/structure-packing/。