NULL と 0
なぜだか最近 C++ ネタが多いな。研究では Java か Python か Shell Script がほとんどなんだけど。
ここでは、NULLは((void*)0)であって、0ではないのだから、場合によっては動作が違うよ……ということが書かれています。
でも面白いことに、C++ではNULLと0は完全に同じです。#define NULL 0とされています。
そもそも、もしもNULLの型がvoid*だったのなら、C++では、char*に対してそのままの代入が行えません。
なのでC++では、NULLと0は完全に同じものです。(UNIXだと、違うとでも言うのでしょうか?)
ええと、C++ では NULL と 0 が同一なんて規定があったっけ? NULL マクロを使うのをやめてリテラルの 0 を使えという話はありがちだけど、とりあえず GCC-4.0 では NULL と 0 が同一なわけではない。以下 64bit 環境での結果。
% cat test.cpp #include <cstddef> #include <iostream> int main() { std::cout << "NULL: " << sizeof(NULL) << std::endl << "0: " << sizeof(0) << std::endl << "0L: " << sizeof(0L) << std::endl; return NULL; } % g++ -E test.cpp | tail -n 8 int main() { std::cout << "NULL: " << sizeof(__null) << std::endl << "0: " << sizeof(0) << std::endl << "0L: " << sizeof(0L) << std::endl; return __null; } % g++ -Wall test.cpp test.cpp: In function `int main()': test.cpp:9: warning: converting to non-pointer type `int' from NULL % ./a.out NULL: 8 0: 4 0L: 8
現象まとめ。
- NULL は 0 に展開されるわけではなくて、__null に展開されている
- int であるべきところに NULL って書いたらきっちり「NULLから非ポインタへの変換」と警告が出る
- 実際に 64bit 環境では 0 と NULL のサイズは異なる
まぁ、常に 「#define NULL 0」だと思っていたら大間違いだということです。