Wednesday, June 11, 2008

Null pointer constants

I personally use the literal 0 instead of NULL for null pointers, although this usually quickly degrades into a religious discussion (like any coding standard discussion). However, I was recently asked whether
  const int null = 0;
  char* p = null;
was valid or not. Visual C++ 2005 was accepting that code, but since we need to port this code under many different platforms, we had to try it on gcc 2.96, which barfed about converting an int to a char*. My first guess was that the literal 0 could be converted to a pointer, but not a constant int variable and that Visual C++ was overly permissive. Of course, I was wrong. Here's from §4.10:
A null pointer constant is an integral constant expression (§5.19) rvalue of integer type that evaluates to zero. [...]
And §5.19 reads:
[...] An integral constant-expression can involve only literals, enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions, non-type template parameters of integral or enumeration types, and sizeof expressions.
Therefore,
  const int null = 0;
is a constant expression, which means
  char* p = null;
is perfectly well defined. gcc 3.3.1 had a bug reported about this (I suspect the bug had always been present). It was fixed in 4.0.0. It was also quickly discussed by the standard commitee. In conclusion, gcc is wrong and the code is right. However, we're stuck with gcc, so we changed the code. Sigh.