Hacker News new | ask | show | jobs
by eeadc 4678 days ago
That's simply not true. There is the rule, that NULL must be equal to (void *)0. I had also several discussions about that topic, but it's part of at least C99 and C11.
1 comments

Yes, (void * )0 gives a null pointer. I mentioned that. However, that doesn't mean all the bits of a null pointer are required to be all 0. The actual machine representation of a null pointer is implementation-defined. The only requirement C99 places on the actual value of a null pointer is that it compares unequal to a pointer to any object or function, and any two null pointers compare equal. See section 6.3.2.3 paragraphs 3 and 4:

   An integer constant expression with the value 0, or
   such an expression cast to type void *, is called a
   null pointer constant. If a null pointer constant
   is converted to a pointer type, the resulting pointer,
   called a null pointer, is guaranteed to compare unequal
   to a pointer to any object or function.

   Conversion of a null pointer to another pointer type
   yields a null pointer of that type. Any two null pointers
   shall compare equal.
If you do this:

   int pv = 0;
   char * p = (char *)pv;
you are not guaranteed to have p set to a null pointer, because the zero you are casting and assigning is not an integer constant zero. The behavior is implementation-defined, as is going the other way. Section 6.3.2.3 paragraphs 5 and 6:

   An integer may be converted to any pointer type. Except
   as previously specified, the result is implementation-defined,
   might not be correctly aligned, might not point to an entity
   of the referenced type, and might be a trap representation.

   Any pointer type may be converted to an integer type. Except
   as previously specified, the result is implementation-defined.
   If the result cannot be represented in the integer type, the
   behavior is undefined. The result need not be in the range of
   values of any integer type.
This should be okay, though:

   char *p1 = 0;
   int pv = (intptr_t)p1;
   char *p2 = (char *)pv;
I.e. NULL must round-trip through intptr_t.