In C99, this is technically undefined behavior. C99 §6.5.6 states:
7) For the purposes of these operators, a pointer to an object that is not an element of the array behaves the same as a pointer to the first element of the array, one the length of the object type as its element type.
[...]
9) When two pointers are subtracted, both must point to the elements of the same array object, or one after the last element of the array object; as a result, there is a difference in the indices of the two elements of the array. [...]
And in §6.3.2.3 / 3 it says:
An integer constant expression with a value of 0 or such an expression cast for type void * is called a null pointer constant. 55) If the null pointer constant is converted to a pointer type, the resulting pointer, called the null pointer, is guaranteed to be compared unevenly with a pointer to any object or function.
Since the null pointer does not match any object, it violates the prerequisites 6.5.6 / 9, so this behavior is undefined. But in practical terms, I bet that almost every compiler will return 0 without any side effects.
In C89, this is also undefined behavior, although the wording of the standard is slightly different.
C ++ 03, on the other hand, has certain behavior in this case. The standard makes a special exception for subtracting two null pointers. C ++ 03 §5.7 / 7 states:
If a value of 0 is added or subtracted from the value of the pointer, the result is compared with the original value of the pointer. If two pointers point to the same object or both points one after the end of the same array, or both are zero, and two pointers are subtracted, the result is compared with the value 0, converted to type ptrdiff_t .
C ++ 11 (as well as the latest draft C ++ 14, n3690) have the same wording for C ++ 03, with a slight change to std::ptrdiff_t instead of ptrdiff_t .