Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which of these will create a null pointer?

The standard says that dereferencing the null pointer leads to undefined behaviour. But what is "the null pointer"? In the following code, what we call "the null pointer":

struct X
{
  static X* get() { return reinterpret_cast<X*>(1); }
  void f() { }
};

int main()
{
  X* x = 0;
  (*x).f(); // the null pointer?  (1)

  x = X::get();
  (*x).f(); // the null pointer?  (2)

  x = reinterpret_cast<X*>( X::get() - X::get() );
  (*x).f(); // the null pointer?  (3)

  (*(X*)0).f(); // I think that this the only null pointer here (4)
}

My thought is that dereferencing of the null pointer takes place only in the last case. Am I right? Is there difference between compile time null pointers and runtime according to C++ Standard?

like image 586
big-z Avatar asked Mar 24 '10 22:03

big-z


3 Answers

Only the first and the last are null pointers. The others are results of reinterpret_cast and thus operate on implementation defined pointer values. Whether the behavior is undefined for them depends on whether there is an object at the address you casted to.

like image 70
Johannes Schaub - litb Avatar answered Oct 22 '22 11:10

Johannes Schaub - litb


An integer constant expression that evaluates to 0 is valid as a null pointer, so the first case is also dereferencing a null pointer.

A pointer which is set to 0 via some arithmetic calculation is not necessarily a null pointer. In most implementations it will behave in the same way as a null pointer, but this is not guaranteed by the standard.

like image 12
Mark Byers Avatar answered Oct 22 '22 09:10

Mark Byers


C++ Standard (2003) 4.10

4.10 Pointer conversions

1 A null pointer constant is an integral constant expression (5.19) 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 (4.4).

5.2.10 Reinterpret cast

Note 64) Converting an integral constant expression (5.19) with value zero always yields a null pointer (4.10), but converting other expressions that happen to have value zero need not yield a null pointer.

1) X* x = 0; (*x).f(); Yes. 0 is integral constant expression and is converted to the null pointer constant. Then null pointer constant can be converted to the null pointer value.

2) x = X::get(); no, see note 64 in 5.2.10

3) x = reinterpret_cast<X*>( X::get() - X::get() ); no, see note 64 in 5.2.10

4) ((X)0).f(); Yes. 0 (integral constant expression) --> the null pointer constant --> the null pointer value.

like image 7
Alexey Malistov Avatar answered Oct 22 '22 10:10

Alexey Malistov