次のC++コードに出くわしました:
#define OFFSETOF_MEMBER(t, f) \
(reinterpret_cast<uintptr_t>(&reinterpret_cast<t*>(16)->f) - static_cast<uintptr_t>(16u)) // NOLINT
ここで、t は型、f はフィールド名です。なぜ reinterpret_cast のパラメータとして整数 16 を指定できるのだろうか。
次のC++コードに出くわしました:
#define OFFSETOF_MEMBER(t, f) \
(reinterpret_cast<uintptr_t>(&reinterpret_cast<t*>(16)->f) - static_cast<uintptr_t>(16u)) // NOLINT
ここで、t は型、f はフィールド名です。なぜ reinterpret_cast のパラメータとして整数 16 を指定できるのだろうか。
整数 16 は単なるメモリ アドレスです。式reinterpret_cast<t*>(16)
は単に「アドレス 16 のオブジェクトを型として解釈する」という意味ですが、アドレスにそのようなオブジェクトt
がないことがわかります。t
理論的に16
は、任意の 4x (32 ビット) または 8x (64 ビット) の整数に置き換えることができます。を選択する0
と、マクロは次のように簡略化できます。
#define OFFSETOF_MEMBER(t, f) \
(reinterpret_cast<uintptr_t>(&reinterpret_cast<t*>(0)->f))
詳細については、 offsetofを参照してください。