首页 > 解决方案 > 工会成员的偏移量总是为零吗?

问题描述

C++ 是否保证任何联合及其成员offsetof(U, m)始终返回零,或者是否存在非零的情况?Um

union U {
  M m;
  ...
};

标签: c++union

解决方案


是的,它总是为零。 6.8.2.4

两个对象 a 和 b 是指针可互转换的,如果:
— 它们是同一个对象,或者
— 一个是联合对象,另一个是该对象的非静态数据成员 ([class.union]),或者
— 一个是一个标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的任何基类子对象([class.mem]),或
— 存在一个对象 c,使得 a 和 c 是指针可互转换的,而 c 和 b 是指针可互转换的。
如果两个对象是指针可互转换的,那么它们具有相同的地址,并且可以通过 reinterpret_cast 从指向另一个的指针获得指向其中一个的指针。[注意:数组对象和它的第一个元素不是指针可互转换的,即使它们具有相同的地址。——尾注]

由于它们是指针可互转换的并且共享相同的地址,offsetof(U, m)因此应该为零。

更新:

如果联合U不是标准布局,则有条件支持。17.2.4.1

宏 offsetof(type, member-designator) 与 C 标准库头文件 <stddef.h> 中的相应宏具有相同的语义,但在本文档中接受一组受限的类型参数。有条件地支持使用非标准布局类 ([class.prop]) 的 offsetof 宏。 183 表达式 offsetof(type, member-designator) 从不依赖于类型,它依赖于值,如果并且仅当类型依赖时。将 offsetof 宏应用于静态数据成员或函数成员的结果未定义。offsetof 宏调用的任何操作都不应抛出异常,并且 noexcept(offsetof(type, member-designator)) 应为真。

但是一旦它被支持,唯一有意义的结果就是零,因为它们共享相同的地址。


推荐阅读