Does this avoid UB
c, language-lawyer, undefined-behavior
Solution
Both definitions are undefined behavior: in the first definition a null pointer is dereferenced and in your second definition you are dereferencing an invalid pointer (the pointer does not point to a valid object). It is not possible in C to write a portable version of `offsetof` macro.
Defect Report #44 says:
"In particular, this is why the offsetof macro exists: there was otherwise no portable means to compute such translation-time constants."
(DR#44 is for C89 but nothing has changed in the language in C99 and C11 that would allow a portable implementation.)
Problem
This question is more of an academic one, seeing as there is no valid reason to write your own `offsetof` macro anymore. Nevertheless, I've seen this home-grown implementation pop-up here and there: ``` #define offsetof(s, m) ((size_t) &(((s *)0)->m)) ``` Which is, technically speaking, dereferencing a NULL pointer (AFAIKT): C11(ISO/IEC 9899:201x) §6.3.2.3 Pointers Section 3 An integer constant expression with the value `0`, or such an expression cast to type `void *`, is called a null pointer constant So the above implementation is, according to how I read the standard, the same as writing: ``` #define offsetof(s, m) ((size_t) &(((s *)NULL)->m)) ``` It does make me wonder that, by changing one tiny detail, the following definition of `offsetof` would be completely legal, and reliable: ``` #define offsetof(s, m) (((size_t)&(((s *) 1)->m)) - 1) ``` Seeing as, instead of 0, 1 is used as a pointer, and I subtract 1 at the end, the result should be the same. I'm no longer using a NULL pointer. As far as I can tell the results are the same. So basically: is there any reason why using `1` instead of `0` in this `offsetof` definition might not work? Can it still cause UB in certain cases, and if so: when and how? Basically, what I'm asking here is: Am I missing anything here?