Difference in definition of null pointer in C99 and C++03

Viewed 280

N2431 is the paper that introduces nullptr. It says:

The current C++ standard provides the special rule that 0 is both an integer constant and a null pointer constant. From [C++03] clause 4.10:

A null pointer constant is an integral constant expression (expr.const) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (conv.qual).

This formulation is based on the original K&R C definition and differs from the definition in C89 and C99. The C standard [C99] says (clause 6.3.2.3):

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.[55] 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.

Let's ignore "[c++03] formulation is based on the original K&R C definition" part and focus on "[c++03 formulation] differs from the definition in [...] C99".

It is not clear to me in which way do C++03 and C99 definitions differ. Yes, they have different formal definitions in the written standard (as we can see the citations differ), but what does that mean from practical perspective? Do they really differ? If I'm reading the article correctly, its tone implies that there are differences. If so, what are they? I am not able to comprehend/understand the difference based on the citations from standards.

I don't ask specifically how C++03 or C99 null pointer is defined, represented and/or implemented. My question is about how C++03 and C99 null pointer definitions (and perhaps their implementations, if this is important to demonstrate in order to answer this question) differ, and the answer can contain the explanations of definitions of C++03 and C99 null pointers, but only as a helping point to demonstrate the difference or show the lack of it. That is, only providing the definitions or the explanations of the definitions of each one is not considered an answer to this question.

I am fully aware that nullptr is the preferred way of expressing null pointer in C++11 and later. This is not the question.

2 Answers

The reason that the standard doesn’t allow (void*)0 as a null pointer constant is that a void* is not convertible to any other pointer types (other than cv-qualified void*). In C you can do void *p = 0; int *ip = p;. In C++ the implicit conversion to int* is not allowed.

In C you have

An integer constant expression with the value 0, or such an expression cast to type void *

which means integer constants with the value of 0 and (void*)0 are valid null pointer constants.

In C++ you have

A null pointer constant is an integral constant expression (expr.const) rvalue of integer type that evaluates to zero

Which means only integer constants with the value of 0 are valid null pointer constants.

Related