C vs C ++结构alignment

在最近的一次关于C ++结构体字段alignment的问题上,我被问到了这个问题,并且理论上C和C ++在结构打包中遵循相同的策略。

Hovewer,这是错误的假设。 面试官说,总的来说,C和C ++以不同的方式打包,我们不应该期待相反的结果。 恕我直言,这是奇怪的声明。 C ++中没有用于双C / C ++头文件的pack "C"限定符。

所以实际上,这可能意味着你不能在C ++中创build一个结构体,并把它传递给一个C库,因为通常它的字段将以不同的方式alignment,并且具有不同的偏移量。 但事实上,大多数程序员认真地依赖于这种互操作性,直到他们将一个指针转换为一个C POD结构为止,以及一些辅助方法引用C ++包装。 你能澄清这个问题吗?

C和C ++语言标准都没有提出struct padding的要求,而是把它作为编译器的实现细节。 对此的严格解释意味着不能保证两者之间的结构是相同的。

然而,实际上,如果需要的话,具有C和C ++的工具链(例如GCC或Clang)的给定版本可以以相同的方式打包相同的结构。 如果没有这个,世界上很多生产代码根本无法工作。 但是,这是工具链给出的保证,而不是语言。

值得注意的是,如果你要声明一个类似于C原型的结构体,但是添加了访问说明符( privatepublicprotected ),那么布局将会改变,但是由于结构体不再相同。

这显然是错误的(面试官方)。 很明显,对于任何使用处理结构的低级API (例如networkingAPI)的人来说,C和C ++的struct packing是相同的。 所有这些都是C函数,它接受'C'结构,但是从C ++代码安全地调用了数千万次。

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

当开发C ++时,开发者发现C程序员依赖于C ++开发人员不想保证的一些东西,但是不保证它们意味着很多C代码也是有效的C ++代码在使用时会被破坏作为C ++代码。 不可取。

这就是为什么他们发明了“POD”结构:没有使用任何C ++特性的结构在C ++程序中的行为与在C程序中的行为完全一样(除了实现定义的行为可能会改变,因为C编译器和一个C ++编译器显然不是相同的实现,另一方面,C ++编译器可能只是从C编译器复制实现定义)。

如果你把任何普通的C结构也是一个有效的C ++结构体(例如没有名字为“class”的成员),那么你只需在左括号后面加上“public:”,那么它的布局,成员顺序,alignment等都可以改变。 即使所有的结构成员默认都是公共的,所以没有什么改变。 除了因为“公众”,这不是一个POD了。

Interesting Posts