命名空间
变体
操作

offsetof

来自 cppreference.com
< cpp‎ | types
 
 
实用工具库
语言支持
类型支持 (基本类型,RTTI)
库功能测试宏 (C++20)
动态内存管理
程序实用工具
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三方比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
类型支持
基本类型
固定宽度整数类型 (C++11)
固定宽度浮点类型 (C++23)
(C++11)    
(C++17)
(C++11)
offsetof

数值限制
C 数值限制接口
运行时类型信息
 
定义在头文件 <cstddef>
#define offsetof(type, member) /* implementation-defined */

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 DR 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; // warning: 'S' is a non-standard-layout type
};
 
int main()
{
    std::cout
        << "offset of char   m0 = " << offsetof(S, m0) << '\n'
        << "offset of double m1 = " << offsetof(S, m1) << '\n'
        << "offset of short  m2 = " << offsetof(S, m2) << '\n'
        << "offset of char   m3 = " << offsetof(S, m3) << '\n';
}

可能的输出

offset of char   m0 = 0
offset of double m1 = 8
offset of short  m2 = 16
offset of char   m3 = 18

[编辑] 缺陷报告

以下行为变更缺陷报告已追溯应用于之前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
CWG 273 C++98 如果一元 operator& 被重载,则 offsetof 可能无法正常工作 即使 operator& 被重载,也需要正常工作
如果 operator& 被重载
LWG 306 C++98 type 不是 PODType 时,行为未指定 在这种情况下,结果是未定义的
LWG 449 C++98 offsetof 的其他要求被
通过 LWG 问题 306 的解决方案删除
将它们添加回来

[编辑] 另请参阅

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