offsetof

来自cppreference.com
< cpp‎ | types


 
 
 
 
在标头 <cstddef> 定义
#define offsetof(type, member) /* 由实现定义 */

offsetof 会展开成 std::size_t 类型的整数常量表达式,它的值是从指定类型对象的开始到其指定子对象的字节数偏移,其中包括可能有的填充位

给定拥有静态存储期的 type 类型的对象 oo.member 应当是指代 o 的子对象的左值常量表达式,否则行为未定义。特别是 member静态数据成员位域成员函数的情况下行为未定义。

如果 type 不是简旧数据类型(PODType) (C++11 前)标准布局类型(C++11 起),那么offsetof 的结果未定义(C++17 前)offsetof 宏的使用受条件性支持(C++17 起)

表达式 offsetof(type, member) 不会类型待决,而且它当且仅当 type 是待决类型时才会是值待决的。

目录

[编辑]异常

offsetof 不会抛出异常。

表达式 noexcept(offsetof(type, member)) 始终求值为 true

(C++11 起)

[编辑]注解

标准布局类型的首个成员的偏移始终是零(空基类优化是强制的)。

(C++11 起)

offsetof 不能以标准 C++ 实现,并要求编译器支持:GCCLLVM

不限制 member 为直接成员。它能指代某个给定成员的子对象,例如数组成员的元素。这是由 C 缺陷报告 496 指定的。

C23 中指定在 offsetof 中定义含有不带括号的逗号的新类型为未定义行为,而这种用法通常不被实现在 C++ 模式支持:所有已知实现都拒绝 offsetof(struct Foo {int a, b;}, a)

[编辑]示例

#include <cstddef>#include <iostream>   struct S {char m0;double m1;short m2;char m3;// private: int z; // 警告:'S' 不是标准布局类型};   int main(){std::cout<<"char m0 的偏移 = "<< offsetof(S, m0)<<'\n'<<"double m1 的偏移 = "<< offsetof(S, m1)<<'\n'<<"short m2 的偏移 = "<< offsetof(S, m2)<<'\n'<<"char m3 的偏移 = "<< offsetof(S, m3)<<'\n';}

可能的输出:

char m0 的偏移 = 0 double m1 的偏移 = 8 short m2 的偏移 = 16 char m3 的偏移 = 18

[编辑]缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
CWG 273 C++98 重载了一元 operator&offsetof 可能无法正常使用 即使重载了 operator& 也必须正常使用
LWG 306 C++98 未指定在 type 不是 简旧数据类型(PODType) 的情况下的行为 此时结果未定义
LWG 449 C++98 LWG 问题 306 的解决方案移除了 offsetof 的其他要求 重新添加这些要求

[编辑]参阅

sizeof 运算符返回的无符号整数类型
(typedef)[编辑]
检查类型是否为标准布局类型
(类模板)[编辑]
offsetof 的 C 文档
close