C++におけるNULLポインタ

NULLポインタ

NULLはC言語との互換性のために残されているマクロ定義。主にBad Pointer(不適切ポインタ:メモリ確保されていないポインタ)を表すために使われていた*1. C++で(C言語で言う)NULLを表現したい場合、普通は0を使用すべき. 0は任意の型のヌルポインタに変換される事が保証されているので、 どんなNULLマクロよりも安全.

0の欠点

0を使用する方法にもひとつだけ欠点がある. それは、0は任意の型のヌルポインタに変換できますが、 整数型でもあります。 なので、クラス型を引数にもち、ヌルポインタも引数として許す関数と 整数型を引数に取る関数を同時に定義すると、 ヌルを渡した際に常に整数型を引数に取る関数が呼び出されることになる.このような関数のオーバーロードはしてはいけない.

void Func(int i);
void Func(bool b);

void Func(bool b) {                                                                                                           
  cout <<__PRETTY_FUNCTION__<<endl;                                                                                           
}                                                                                                                             
                                                                                                                              
void Func(int b) {                                                                                                            
  cout <<__PRETTY_FUNCTION__<<endl;                                                                                           
}                                                                                                                             

void main()
{
     Func(0);         
     Func(NULL); // Func(0)が呼び出される
} 

[note : g++ -std=c++98 では error: call of overloaded ‘Func(NULL)’ is ambiguous]

Func(NULL)で実際呼び出されるのは Func(int i) である. コンパイラから見たらNULL はポインタではなく、ただの 0 なので当然といえば当然...

NULLの欠点

NULLはマクロ定義なので、処理系依存なので、NULLは処理系によっては 思ったとおりの動作をしない可能性がある。ただしそのよな系は近年は極めてまれである.

c++11

C++11ではnullptrと呼ばれるnull pointerに変換可能だが他の変数に変換不能なキーワード.

Reference

Stroustrup: C++ Style and Technique FAQ

Should I use NULL or 0?

In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days. If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, "nullptr" will be a keyword.

*1:c,c++に限らず全てのポインタはbad valueで初期化される.bad pointerを参照しようとすると、プログラムの予期しないところでクラッシュして非常にやっかいだ. Java や他の runtime oriented language,ではポインタは常にNULL値で始まるため、そのようなポインタを参照しようとすると必ず検知される。Javaデバッグしやすい理由はここから来る.