Not yet cleared.
Here how it is able differentiate between accessing address and accessing a member.
Suppose in below statement
#define offsetof(s,m) (size_t)&(((s *)0)->m)

It is accessing address only. But before address operator, it is accessing member using ((s *)0)->m. How this is different from ((i*)0)->j.