Hacker News new | ask | show | jobs
by tzs 4678 days ago
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.
1 comments

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.