asker raise a question about #define offsetof(st, m) \
((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
deference null(0) pointer and there is no segment fault.
JaredPar's answer pointed out:
The -> operator is used above but it's not used to access the value. Instead it's used to grab the address of the value. Here is a non-macro code sample that should make it a bit clearer
SomeType *pSomeType = GetTheValue(); int* pMember = &(pSomeType->SomeIntMember);
The second line does not actually cause a dereference (implementation dependent). It simply returns the address of SomeIntMember within the pSomeType value.
My question is how to prove int* pMember = &(pSomeType->SomeIntMember);
just assigns SomeIntMember's address to pMember without deferencing pSomeType.
Is there any iso c++ standard? or is there any method?
EDIT:
Although the question I posted is about c, I want c++ answer, so I tag this question c++.
If there is something in c++ standard, it is better.
Else, I hope to see something to prove JaredPar's conclusion, e.g., xaxxon posted the assembly, or how specific compiler implement.
If answers hold int* pMember = &(pSomeType->SomeIntMember);
does make deference to pSomeType, then why offsetof's implemention(#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
) is valid?
UPDATE:
Thanks for all the comments and answers, now I understand that #define offsetof(st, m) ((size_t) ( (char*)&((st*)(0))->m - (char)0))
is one of implementions in c, not in c++.
Also, I find msvc's implemention, #define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
, but it is a little complex to me, can someone give an expression? Thanks in advance.