0

Consider the following code:

#include <inttypes.h>

struct test {
    int a;
    long b;
};

int main(void){
    intptr_t ptr = (intptr_t) &(((struct test *)NULL)->b);
    printf("%"PRIiPTR"\n", ptr); //prints 8
    //...
}

I've been using this sort of construction for pretty long time to determine offset of struct member, but now questioned if this construction a well defined in terms of the Standard standpoint.

The thing that's not clear to me is why is it legitimate to perform indirection on a NULL pointer with later taking address?

Some Name
  • 8,555
  • 5
  • 27
  • 77
  • Per C if "a null pointer is guaranteed to compare unequal to a pointer to any object" and "any two null pointers shall compare equal", then a null pointer is not a pointer to object. Hence, "a postfix expression followed by the `->` operator and an identifier" does _not_ designate a member of a structure object. Hence, `((struct test *)NULL)->b` violates semantics of the `->` operator. – pmor Aug 26 '22 at 22:16

1 Answers1

5

This is not valid code, as it dereferences a NULL pointer and attempts to obtain an lvalue for a non-existent object.

There is a language construct that gives the offset of a struct member, namely the offsetof macro.

Although it is possible that such a macro could expand to an expression similar to what you have, that macro is considered part of the implementation, and such code can do things that "user" code is not allowed to do

dbush
  • 205,898
  • 23
  • 218
  • 273