offsetof
來自 cppreference.com
定義於標頭檔案 <cstddef> |
||
#define offsetof(type, member) /* implementation-defined */ |
||
宏 offsetof 展開為 std::size_t 型別的整型常量表達式,其值為從指定型別物件的起始到其指定子物件的偏移量(以位元組為單位),包括任何 填充位。
給定一個型別為 type
且具有靜態儲存期的物件 o,o.member 應當是一個 lvalue 常量表達式,它引用 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++ 中實現,需要編譯器支援:GCC、LLVM。
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++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
CWG 273 | C++98 | 如果過載了一元 operator& ,offsetof 可能無法工作 |
即使過載了 operator& ,也要求正確工作如果 operator& 被過載 |
LWG 306 | C++98 | 當 type 不是 PODType 時,行為未指定 |
在這種情況下結果未定義 |
LWG 449 | C++98 | offsetof 的其他要求被 LWG issue 306 的解決方案移除被 LWG issue 306 的解決方案移除 |
已添加回來 |
[編輯] 參閱
由 sizeof 運算子返回的無符號整型 (typedef) | |
(C++11) |
檢查型別是否為標準佈局型別 (類模板) |
C 文件 關於 offsetof
|