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)
offsetof
数值极限
C 数值极限接口
运行时类型信息
 
在标头 <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)
检查类型是否为标准布局类型
(类模板)