名稱空間
變體
操作

offsetof

來自 cppreference.com
< cpp‎ | 型別
 
 
 
型別支援
基本型別
定寬整數型別 (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 應當是一個 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++ 中實現,需要編譯器支援: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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
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 文件 關於 offsetof