in MSVC, offsetof
implemented as:
#define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
My question is:
why
reinterpret_cast
?why
volatile
?why
size_t
, notptrdiff_t
?
in MSVC, offsetof
implemented as:
#define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
My question is:
why reinterpret_cast
?
why volatile
?
why size_t
, not ptrdiff_t
?
&reinterpret_cast<char const volatile&>(expr)
is also the code used to implement std::addressof
. std::addressof
is necessary because C++ allows overloading the unary-&
operator, but the actual library function can't be used here prior to C++17, when it is marked constexpr
.
size_t
rather than ptrdiff_t
because that's what the standard says it has to return.
Edit: while technically the standard doesn't directly specify this case, in practice compilers are forced to cover it due to other logic and historical practice.
why reinterpret_cast?
reinterpret_cast<>() is the only way to convert a pointer to a size_t
why volatile?
volatile prevents the optimizer to optimize away the expression (((s*)0)->m))
.
why size_t, not ptrdiff_t?
offsetof()
returns an offset, not the number of elements between two pointers.