名前空間
変種
操作

offsetof

From cppreference.com
< C‎ |
ヘッダー <stddef.h> で定義
#define offsetof(type, member) /*実装定義*/

マクロ offsetof は、指定された型のオブジェクトの先頭から、指定されたメンバ(パディングを含む)までのオフセットをバイト単位で表す、size_t 型の整数定数式に展開されます。

静的記憶域期間を持つ `type` 型のオブジェクト `o` が与えられた場合、&(o.member) はアドレス定数式であり、`o` のサブオブジェクトを指します。それ以外の場合、動作は未定義です。

`type` で指定された型名に、対応する括弧の間にないカンマが含まれている場合、動作は未定義です。

(C23以降)

目次

[編集] 注釈

ビットフィールドメンバに offsetof を適用した場合、ビットフィールドのアドレスを取得できないため、動作は未定義です。

member は直接のメンバに限定されません。配列メンバの要素など、指定されたメンバのサブオブジェクトを指すことができます。

C23 では、新しい型を定義する際に括弧で囲まれていないカンマを指定することが未定義の動作であると規定されていますが、このような使用法は、以前のモードでも一般的にサポートされていません。例えば、offsetof(struct Foo { int a, b; }, a) は通常コンパイルに失敗します。

typeof を使用すると、新しい型の定義におけるカンマの悪影響を回避できます。例えば、offsetof(typeof(struct { int i, j; }), i) は well-defined です。

(C23以降)

[編集]

#include <stdio.h>
#include <stddef.h>
 
struct S {
    char c;
    double d;
};
 
int main(void)
{
    printf("the first element is at offset %zu\n", offsetof(struct S, c));
    printf("the double is at offset %zu\n", offsetof(struct S, d));
}

実行結果の例

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

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に発行されたC規格に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
DR 496 C89 構造体とそのメンバのみが言及されていました。 共用体やその他のサブオブジェクトもサポートされています。

[編集] 関連項目

sizeof 演算子が返す符号無し整数型
(typedef) [編集]
English 日本語 中文(简体) 中文(繁體)