offsetof

来自cppreference.com
< cpp‎ | types
 
 
工具库
通用工具
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)
(C++20)
swap 与类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)

初等字符串转换
(C++17)
(C++17)
栈踪
 
类型支持
基本类型
基础类型
定宽整数类型 (C++11)
(C++11)
offsetof
数值极限
C 数值极限接口
运行时类型信息
类型特性
类型类别
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
类型属性
(C++11)
(C++11)
(C++14)
(C++11)
(C++11)(C++20 前)
(C++11)(C++20 中弃用)
(C++11)
类型特性常量
元函数
(C++17)
常量求值语境
受支持操作
关系与属性查询
类型修改
(C++11)(C++11)(C++11)
类型变换
(C++11)
(C++11)
(C++17)
(C++11)(C++20 前)(C++17)
 
定义于头文件 <cstddef>
#define offsetof(type, member) /*implementation-defined*/

offsetof 展开成 std::size_t 类型的整数常量表达式,其值是从指定类型对象开始到其指定子对象的字节数偏移,若有填充字节则包括之。

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

type 不是简旧数据类型 (PODType) (C++11 前)标准布局类型 (C++11 起),则行为未定义 (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++ 模式支持: ICC 与 GCC 的一些旧版本支持 offsetof(struct Foo { int a; }, a) ,而所有已知实现都拒绝 offsetof(struct Foo { int a, b; }, a) ,因为 Foo 定义中的逗号。

示例

#include <iostream>
#include <cstddef>
struct S {
    char c;
    double d;
};
int main()
{
    std::cout << "the first element is at offset " << offsetof(S, c) << '\n'
              << "the double is at offset " << offsetof(S, d) << '\n';
}

可能的输出:

the first element is at offset 0
the double is at offset 8

缺陷报告

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

DR 应用于 出版时的行为 正确行为
CWG 273 C++98 若重载了一元 operator&offsetof 可能无法工作 即使重载了 operator& 也要求它正确工作

参阅

sizeof 运算符返回的无符号整数类型
(typedef)
检查是否是一个标准布局类型
(类模板)