offsetof
来自cppreference.com
定义于头文件 <cstddef>
|
||
#define offsetof(type, member) /*implementation-defined*/ |
||
宏 offsetof 展开成 std::size_t 类型的整数常量表达式,其值是从指定类型对象开始到其指定子对象的字节数偏移,若有填充字节则包括之。
给定拥有静态存储期的 type
类型对象 o
, o.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++ 实现,并要求编译器支持: GCC 、 LLVM 。
不限制 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) | |
(C++11) |
检查是否是一个标准布局类型 (类模板) |