C vs C++ struct alignment

Min*_*eat 62 c c++ struct pointers object-layout

我在最近的一次采访中被问到有关C++结构字段对齐的问题,并且理论上C和C++在结构打包中遵循相同的策略.

Hovewer,这是错误的假设.采访者说,一般来说,C和C++以不同的方式包装结构,我们永远不应该期待相反的结果.恕我直言,这是一个奇怪的声明.pack "C"在C++中没有用于双语C/C++头文件的结构限定符.

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

Sam*_*all 68

C和C++语言标准都没有对struct padding的要求,并将其作为编译器实现细节.对此的严格解释意味着无法保证两者之间的结构相同.

然而,在实践中,如果需要,能够同时使用C和C++(例如GCC或Clang)的工具链的给定版本可以以相同的方式打包相同的结构.如果没有这个,世界上许多生产代码根本就行不通.然而,这是工具链给出的保证,而不是语言.

值得注意的是,如果要声明与C原始类似的结构,但添加了访问说明符(private,publicprotected),则布局会发生变化,但由于结构不再相同,所以这有点延伸.

  • 没有编译器错误.一个extC块保证了它内部的C语义:没有名称修改(!),结构对齐到C的版本[_if_它是不同的 - IMO,来自访问者的概念即使没有extC气味他们也不匹配],并且_not_定义类型.这是一个"未来的证明".我们都在为此而旋转,因为一些随机的面试官[可能是一个无知的LL]会催促BS,我们将在之后进行清理.众所周知,已知工具的作用是常识性的事情.否则,许多程序都会中断.这是一个拱形的东西(例如神话拱需要16字节对齐int) (5认同)
  • @Ike你可能会想到`extern"C"int myfnc(return 0;)`但是`extern"C"{struct mystruct {int y; int z; }; }`保证对齐[对于给定的工具链].这告诉C++ _not_插入一个vtable指针,并使用C的对齐[如果它_were_不同].此外,C++将_not_定义`mystruct`作为_type_ [如果它确实,很多C .h会破坏].大多数工具链_want_要互操作(例如gcc和clang,可能是MS),所以它也在那里.它与计算机拱门(例如x86,arm,IBM/370)以及特定的HW对齐限制有关 (4认同)
  • 当我创建一个C .h时,我使用`#ifdef __cplusplus`和`extern"C"...`来确保C++以C兼容的方式解释事物. (3认同)

Ser*_*eyA 29

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

你应该很幸运,你有这个问题.它清楚地表明你不应该在那里工作.

  • 我喜欢这个答案(虽然我也喜欢另一个)作为一个实际的,当之无愧的安慰.听起来好像是面试官脑子里有这种奇怪的概念,而不是试图让人们用这种超级理论的方式思考语言标准假设 - 主要是因为这部分:*"C和C++是不同的包装结构方式,我们永远不应该期待相反."*这听起来不像采访者牢牢抓住他所说的话.这是我期望从一家公司带来的面试问题...... (9认同)
  • 是的,对于糟糕的问题没有好的答案,应该很高兴不在那里工作 (5认同)