DATE : 2006/10/06 (Fri)
C 言語では、ヌルポインタは次のように定義されています。
#define NULL ((void *) 0)
それに対し、C++ では次のように定義されています。
#define NULL 0
C 言語では void 型のポインタだった NULL が、C++ ではただの整数値になっています(コンパイラによって、int 型や long 型に定義されています)。
これは、C++ の型チェックが C 言語と比べて厳しくなったためです。C 言語式では void 型のポインタに型を決定していますが、C++ 式では型を決定付けていません。つまり、C++式の場合は、NULL 値がそのポインタにあった型に自動的に変換されることになります。
(;^ω^)ちなみに、マシンによってはヌルポインタが0番地を指さないものもあります。ただし C や C++ のコンパイラは、ポインタ変数を0で初期化していたり代入、比較しようとしていると、0を自動的にそのマシンに応じたヌルポインタの値に変換してくれます。
しかし、C++ 式では特定の場合に問題が発生します。
次のような関数を考えてみます。
void function(Object* obj) { ... } void function(int i) { ... }
そこで、次のような呼び出しを考えます。
function(NULL);
Object* を引数にとる関数か、int を引数に取る関数のどちらが呼ばれるかは、コンパイラに依存します。そのため、上のようにポインタと int 型とでオーバーロードするのは推奨されていません。
なお、上の関数を正しく呼び出すには、それぞれの引数の型に NULL をキャストします。
このように、C++ の NULL は特別な値ではなくただの整数値であるために、誤解を招きやすい形になっています。そのため、「NULL」を使わずに「0」とそのまま書くことが推奨されています。
(;^ω^)特に、C 言語 → C++ と勉強してくると勘違いしやすいところですね
ちなみに、将来の C++ の仕様では、ヌルポインタを表す予約語が定義されるそうです。
参考文献
(;^ω^)勉強日記の最後にまとめて書こうかと思ったのですが、かなり多くなりそうなので、それぞれのページに付けていこうと思います。
- プログラミングの禁じ手Web版 C++編 - 理念の誤解に関するパターン「C++はC言語の完全な上位互換性があると思い込む」
- C++言語解説 テキストNo.1-5-3 ~ポインタのダークサイド~
- Bjarne Stroustrup's C++ Style and Technique FAQ "Should I use NULL or 0?"
- よりよいC : 空ポインタ定数
- C 言語 FAQ 日本語版「5章 ヌルポインター」
- C++ Topic 「NULLより 0 の方がいい」
- ひげぽん OSとか作っちゃうかMona- [Effective C++][C++] ポインタと数値型とにオーバーロードするのは避けよう 25項
- NULL について