C与C++结构对齐

C vs C++ struct alignment

本文关键字:对齐 结构 C++      更新时间:2023-10-16

在最近的一次采访中,有人问我C++结构字段对齐的问题,我认为C和C++在结构打包中遵循相同的策略。

悬停,这是错误的假设。采访者说,一般来说,C和C++以不同的方式封装结构,我们永远不应该期望相反的结果。IMHO,这是一个奇怪的说法。C++中的结构没有用于双语C/C++头文件的pack "C"限定符。

因此,在实践中,这可能意味着你不能在C++中创建一个结构并将其传递给C库,因为通常情况下,它的字段将以不同的方式对齐,并具有不同的偏移量。但是,事实上,大多数程序员都非常依赖这种互操作性,直到他们用一些辅助方法将指向C POD结构的指针转换为对该结构周围C++包装器的引用。你能澄清一下这件事吗?

C和C++语言标准都不要求结构填充,并将其留给编译器实现细节。对此的严格解释意味着不能保证两者之间的结构是相同的。

然而,在实践中,如果需要,一个既能使用C又能使用C++的工具链的给定版本(如GCC或Clang)可以以相同的方式封装相同的结构。如果没有这一点,世界上许多生产代码根本无法工作。然而,这是工具链提供的保证,而不是语言。

值得注意的是,如果您声明一个与C原始结构类似的结构,但添加了访问说明符(privatepublicprotected),则布局会发生变化,但这有点牵强,因为结构不再相同。

这显然是错误的(在面试官方面)。很明显,对于使用任何处理结构化的低级API(例如,网络API)的任何人来说,结构打包对于C和C++都是相同的。所有这些都是C函数,它们接受"C"结构,但它们每天都会被C++代码安全地调用数百万次。

你应该很幸运有这个问题。这表明你不应该在那里工作。

在开发C++时,开发人员发现C程序员依赖于一些C++开发人员不想保证的东西,但不保证这些东西意味着许多同样有效的C++代码在用作C++代码时会被破坏。不可取。

这就是他们发明"POD"结构的原因:一个不使用任何C++功能的结构在C++程序中的行为与在C程序中的一样(除了实现定义的行为可能会改变之外,因为C编译器和C++编译器显然不是同一个实现。另一方面,C++编译器可能只是从C编译器复制实现定义)。

如果你采用任何一个普通的C结构,它也是一个有效的C++结构(例如,没有名为"class"的成员),然后你只在左大括号后面添加"public:",那么它的布局、成员顺序、对齐方式等都可以改变。尽管所有结构成员在默认情况下都是公共的,但实际上没有什么变化。除了因为"公众":它不再是POD了。