For the purpose of the macro: It assumes that there is an object of type TYPE at address 0 and returns the address of the member which is effectively the offset of the member in the structure.
This explains why this is undefined behaviour.
If E1 has the type “pointer to class X,” then the expression E1->E2
is converted to the equivalent form (*(E1)).E2; *(E1)
will result in undefined behavior with a strict interpretation, and
.E2 converts it to an rvalue, making it undefined behavior for the weak interpretation.
note that this will work the correct result on many compilers .