【发布时间】:2016-02-23 11:10:10
【问题描述】:
在最近的一次采访中,有人问我关于 C++ 结构字段对齐的问题,并且理论上 C 和 C++ 在结构打包中遵循相同的策略。
但是,这是错误的假设。面试官说,通常 C 和 C++ 以不同的方式打包结构,我们不应该期望相反。恕我直言,这是奇怪的说法。 C++ 中的结构没有 pack "C" 限定符,可用于双语 C/C++ 头文件。
因此在实践中,这可能意味着您无法在 C++ 中创建结构并将其传递给 C 库,因为通常它的字段将以不同的方式对齐并具有不同的偏移量。但是,事实上,大多数程序员在使用一些辅助方法将指向 C POD 结构的指针转换为对该结构的 C++ 包装器的引用之前,都非常依赖这种互操作性。你能澄清一下这个问题吗?
【问题讨论】:
-
多么奇怪的问题。如果 C 和 C++ 之间的结构填充不同,我会被搞砸的。也许面试官在一些晦涩难懂的编译器上发现了一些非常奇怪的问题——或者他在想 C 和 C++ 编译器如何可能完全不同,并且期望两个编译器以相同的方式对齐字段并使用相同的填充可能不是我们应该做的事情有信心依赖(但即使在两个 C 编译器或两个 C++ 编译器之间也是如此——与语言无关)。
-
你是对的。打包是处理器实现细节,它确保遵守对齐规则。针对同一处理器的 C 编译器和 C++ 编译器必须处理相同的实现细节。
-
@ISanych,什么? g++/gcc 只是前端。调用什么并不重要 - 就编译过程而言,实际驱动程序是基于文件扩展名调用的(链接不同)。
-
@Olaf 但是由于您不能在 C 中继承,因此 C++ 中的相同结构永远不需要 RTTI 或 v-table 指针。
-
@SergeyA:填充是对齐要求的结果,这就是为什么我在中间使用斜线,而不是和号。您通常不会在没有实际需要的情况下进行填充。 CPU 可能无法通过一条指令访问其本机类型。例如。对于某些 ARM CPU,gcc 为
packedstructs 发出特殊代码,这些代码按字节读取int并将它们组装到寄存器中(反之亦然)。与手动(反)序列化完全相同。而且pack指令无论如何都不是标准的,并非所有编译器都支持。
标签: c++ c pointers struct object-layout