型的には void* であってはいけないはず。標準のドラフトによると、
-4- The macro NULL is an implementation-defined C++ null pointer constant in
this International Standard (conv.ptr).*
[Footnote: Possible definitions include 0 and 0L, but not (void*)0. --- end
foonote]
だと。つまり 64bit でも NULL 使えば問題は起きないんだろうね。可変長引数のみ NULL 使って他は 0 使っておくのが無難って感じだろうか。
そういえば、昔、規格書PDFを買ったような・・・
と遠い記憶をたよりにごそごそと。
んで、出てきたのがこれ。
んーまあ、ほとんど変わってないね
オイラが見ている規格バージョンは以下ね
ISO/IEC14882 Second edition 2003-10-15
(Shinhさんの見てるのはいつのだ??)
関係しそうなところをいくつか抜粋
4.10 Pointer conversions [conv.ptr]
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).
18.1 Types
4 The macro NULL is an implementation-defined C + + null pointer constant in this International Standard
(4.10).180)
Annecx C(informative) Compativility
C.2.2.3 Macro NULL [diff.null]
1 The macro NULL, defined in any of <clocale>, <cstddef>, <cstdio>, <cstdlib>, <cstring>,
<ctime>, or <cwchar>, is an implementation-defined C + + null pointer constant in this International
Standard (18.1).
こうしてみると、null pointer は任意のポインタに変換できるintegral constant expressionと明記してあるので、intへの代入で警告を出すgccはグレーゾーンかも分からんね
(超便利なので否定する気はまったくないが)
追記:
ちなみに、
C++は型チェックが厳しいので、どのNULLマクロよりもただの0を使ったほうが問題が少ないと書いてあり、その下にオススメのNULL定義として
const int NULL = 0;
があげられています(-_-;
#まあ、あの本は先生の趣味で書いた本であって、実用を考えた本ではないらしいから。。
コメント
コメント一覧 (2)
http://www.open-std.org/jtc1/sc22/open/n2356/
と思ったらうちにあったのは FINAL DRAFT とか書いてあってちょっと内容も違うみたいでした。引用個所はここと同じ内容です。
http://www.kuzbass.ru:8086/docs/isocpp/lib-support.html#lib.support.types
NULL より 0 っていうのは、まぁ普通のシーンでは正しいアドバイスなのかな、と思います。 GCC の __null の方が便利そうではありますが、今回みたいに可変長引数でもない限りは問題はない感じですよね。
可変長引数な関数は(compatibility扱いではない)C++の正規の機能なので、そこで不整合が発生するNULLの定義はマズイでしょう。
でも、va_argあたりのマクロは軒並みCから引っ張ってきてる機能ですので、C++的な厳密な型の取り扱いは要求されてないでしょう。だから0を渡してNULLとして解釈してくれないのはOK。
で、if(NULL==0) が常に真になる、integral として、NULLを定義せい。ってのが規格の要求なので、規格準拠だけを考えると政界は
#define NULL 0L
でしょうかね、LP64では。
LLP64(Windows)では
#define NULL 0LL
とすべきに思えます。
こうすれば、if(NULL==0)が常に真であり、かつ、NULLをprintf引数に渡す限りにおいてprintfが意図どおり動きます。と
てゆーか、まとめは、本文でやれ。とかオモタ orz