offsetof
| ヘッダ <cstddef>
|
||
#define offsetof(type, member) /* implementation-defined */
|
||
で定義されます。マクロ offsetof は、std::size_t 型の整数定数式に展開されます。その値は、指定された型のオブジェクトの先頭から、指定された部分オブジェクトまでのオフセット(バイト単位)であり、存在する場合は パディングビット
を含みます。
o型 type で静的記憶域期間を持つオブジェクト o.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++では実装できず、コンパイラのサポートが必要です:
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++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 273 | C++98 |
offsetof
は単項演算子
operator&
がオーバーロードされている場合に
動作しない可能性があった |
operator&
がオーバーロードされていても
正しく動作することが要求される |
| LWG 306 | C++98 |
type
が
PODType
でない場合の動作が規定されていなかった
|
この場合の結果は未定義となる |
| LWG 449 | C++98 |
offsetof
のその他の要件が
LWG issue 306
の解決によって削除されていた
|
これらの要件を再追加 |
関連項目
|
sizeof
演算子によって返される符号なし整数型
(typedef) |
|
|
(C++11)
|
型が
スタンダードレイアウト
型かどうかをチェックする
(クラステンプレート) |
|
Cドキュメント
for
offsetof
|
|