
No.4ベストアンサー
- 回答日時:
(1) NULL を使った方が良いという意見と 0 を使った方が良いという意見の両方がある
規格にはどちらかを使ってはいけないなどという記述はありません。また、C++ では NULL は #define NULL 0 とされるので、実質的にはどちらも同じです。従って、どちらかが推奨されるとしたら、可読性やミスを減らすという観点から議論される事になると思います。因みに、No.3 の #define NULL ((void*)0) は C 言語の場合です。
先ず、NULL を使うと「意味的にそれがポインタを意図している」という事がプログラムの読み手に伝わりやすく、良いとする人があります。(これが、そもそもマクロとして NULL を定義した切っ掛けだと思います。)
しかし、問題点は NULL は単なる 0 に展開されるので、それが「ポインタを意図した 0 である」という事がコンパイラに伝わらないという所にあります。例えば、
void f(int*);
void f(int);
の前者を呼び出そうと思って f(NULL); と書くと f(0); に展開され、実際には後者が呼び出されます。null ポインタを 0 と書いていれば f(0); まで書いた時点で「おや、これはまずいぞ」と気付く可能性が高いですが、NULL と書いていると認識として「NULL はポインタ」という先入観がある為に f(int*) の方が呼び出される様に錯覚してしまいます。因みに、前者の f を正しく呼び出す為には f((int*)NULL) または f((int*)0) とする必要があります (別に 0 と表記していれば何も注意が要らないという訳ではなくやはりキャスト (int*) が必要になりますが、その事に気付きやすいという事です)。
これに対して、そもそもポインタを受け取る関数と整数を受け取る関数を同名で多重定義する事自体が問題なのではないかという反論もあります。つまり、f(int*) f(int) の呼出の問題は、引数に NULL を指定した事に問題があるのではなくその様な多重定義をしてしまった事に問題があるのであって、これは NULL を敬遠する理由にはならないという主張です。
何れにしても、
> 「NULLは単なるマクロなので本来は0を使わなければだめ」
の記述は、違います。0 が推奨される理由は NULL がマクロだからだとかではありません。マクロは偽物で即値が本物なので、即値の方が良いなどという議論は成立しません。マクロの方が読みやすければ、即値ではなくマクロを使うべきです。例えば EXIT_SUCCESS, EXIT_FAILURE, SEEK_SET などのマクロ定数は使った方が分かりやすいプログラムになります。
NULL に関して賛否両論があるのは、C言語からC++への発展の際の矛盾 (ここでは説明しませんでしたが) などの複雑な背景があるからなのです。
(2) C++11 では nullptr
先に述べたように NULL と書くのも 0 と書くのも欠点があるので、それを補う為に C++ の 2011 の規格で nullptr という新しいキーワードが追加されました。今後は、C++11 に対応している新しいコンパイラでは nullptr を使っていくと良いでしょう。(勿論、古いコンパイラでコンパイルできなくなるという問題点はありますが)。
(3) null ポインタを表す整数リテラルは常に 0 です
No.1 補足。
確かに NULL ポインタの「内部表現」(機械の中でどう表されるか) は処理系依存なので、null ポインタのビットパターンをそのまま整数として解釈 (reinterpret_cast) した時に 0 になるとは限りません。しかし、ソースコードの上では常に 0 と表します。なぜならば、整数を普通にポインタに変換 (static_cast) する場合は、整数の 0 と null ポインタが対応する様に変換されるという事が保証されているからです。
No.9
- 回答日時:
>
http://www.curiocube.com/mikata/oop/p1_ch09_nonu …Func(0);
これを後で読んだ場合、ポインタのつもりだったのか数値の0のつもりだったのかわからないと思いますが。
C++で Func(NULL) を「Func(int *)が呼び出されることを意図したコード」というのが、そもそもの間違いですし。
NULLを使うにしろ0を使うにしろFunc(int *)が呼び出されることを意図したコードは
Func((int *)NULL);
Func((int *)0);
です。
>http://www.geocities.jp/bleis_tift/cpp/null.html
NULLの定義は確かに処理系依存ですがNULLポインタの内部表現自体処理系依存です。
NULLが思った通りの動作をしない事があるというのもNULLの使い方を間違えてるくらいしか私には思いつかないです。
3番目については「NULLは単なるマクロなので本来は0を使わなければだめ」といった内容には思えないですけど。
3つ目の参考URLについて、
「@5mingame2 @torotiti 「NULL」はあくまでもC言語用マクロであって、C++では「0」と比較するのが正しいと教わりましたが、(以下略」
とか
「@5mingame2 逆だと思いますよ。ポインタに参照無しは0と書くのが本来で、NULLは単なるマクロです。」
とかあったので、そういう話だと思いました。
No.8
- 回答日時:
補足です。
Microsoftのフォーラムのリンクです。
http://social.msdn.microsoft.com/Forums/ja-JP/80 …
EffectiveC++からの引用があります。
要は0でも弊害が出るのでnullptrを使うべきだが、使えない環境もある。
ソースから検索して置換する場合0だと難しいが、NULLだとやり易い。
という感じかと。
http://msdn.microsoft.com/ja-jp/library/vstudio/ …
回答ありがとうございます。
> ソースから検索して置換する場合0だと難しいが、NULLだとやり易い。
そういえば、そうですね。
NULL にしておくと、後のメンテナンスがしやすいのかもしれません。
No.6
- 回答日時:
#4の方へ
>因みに、No.3 の #define NULL ((void*)0) は C 言語の場合です。
#3では「C言語だと」と前置きしていますが。
C言語でも、そういう話はないですということ書きたかったわけなんだけど。
No.5
- 回答日時:
>「NULLは単なるマクロなので本来は0を使わなければだめ」という話を聞きました。
その発想であれば、マクロは全部使うなということになりますが、マクロは機種やコンパイラ依存の部分を吸収する目的もあるので、その主張には無理があるかと思います。
一応現在は言語使用上NULLポインタは0となっているので、0を使用するのは間違いではありませんが。
参考
http://www7b.biglobe.ne.jp/~robe/cpphtml/html01/ …
現在は可読性を重視するプログラムが主流なので、どちらが読みやすいかですが、個人的にはNULLの方が意味をとらえやすいと思います。
0だと数値と間違えやすい。
その話をした人に何でマクロを使用してはいけないのか聞いて見ましょう。
No.2
- 回答日時:
使ったらダメということでは無いですが、話の背景は間違っていないと思います。
C言語のNULLマクロとC++のNULLマクロは全く異質の物であり
C++におけるNULLマクロはただ単に0と展開されるだけのようです。
また、これは整数のゼロとNULLポインタの区別がつかないことを意味し、
場合によっては多重定義された関数が正しく選択されないという問題が発生します。
この問題を解消するため、新しい標準では
NULLポインタ専用に nullptr というキーワードがあるようです。
【参考】
More C++ Idioms/nullptr
http://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms …
C++11
https://ja.wikipedia.org/wiki/C%2B%2B11
回答ありがとうございます。
話の背景は間違っていない、というのはよくわかりませんでしたが、
全体としては、No.4の回答で理解できました。
No.1
- 回答日時:
そんな嘘っぱち誰に聞いたの?
処理系依存だからNULLが0じゃない場合もありますよん。
この回答への補足
このあたりでしょうか。
http://www.curiocube.com/mikata/oop/p1_ch09_nonu …
ページ最後
「このような失敗を防ぐためには、NULL マクロを使わないことです。いままでこのマクロに親しんできた人には少し辛い別れかもしれませんが、これからは NULL と書くかわりに 0 と書きましょう。」
http://www.geocities.jp/bleis_tift/cpp/null.html
ページ真ん中あたり
「NULLの代用
そもそもNULLはC言語との互換性のために残されているマクロ定義であり、 C++では不必要な存在なのです。
C++で(C言語で言う)NULLを表現したい場合、 0を使用します。 0は任意の型のヌルポインタに変換される事が保証されているので、 どんなNULLマクロよりも安全です。 」
http://togetter.com/li/110100
全体的に
3つ目のページはよくわからない記述もありますが。。。
> 処理系依存だからNULLが0じゃない場合もありますよん。
これはどういう意味(意図)か、ちょっと私にはわかりませんでした。
すいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- MySQL SHOW CREATE TABLE posts;これって何ですか? 3 2022/08/28 22:57
- MySQL `picture` varchar(255) のコマンドで間違いないでしょうか? 1 2022/11/21 04:08
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- MySQL PHPとMySQLを使った掲示板の作り方 1 2022/06/02 13:00
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- PHP PHPでCSVを出力するさいに、ループの中で前の行の値を変更したい 3 2022/10/27 17:44
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
ExcelVBAでのkernel32(64bit)
-
戻り値で構造体を返すことは可...
-
セグメントエラー
-
デバイスハンドルとは?
-
アプリを32bitから64bit移行
-
#define NULL ((void *)0) の弊害
-
Cで作成したDLL関数をVBから呼...
-
fopne で失敗する原因
-
NULLポインタが0でない処理系と...
-
メモリのアドレスからの値の取...
-
不適切なポインタ
-
TCHAR文字列内の検索について
-
参照型で受け取った引数をポイ...
-
ハンドル、アドレス、ポインタ...
-
str[i] は *(str + i) と同義で...
-
構造体のアドレス渡し
-
関数ポインタの高速化のメリット
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
参照型で受け取った引数をポイ...
-
fopne で失敗する原因
-
PASCALとFARの意味
-
LPSTR型の初期化について
-
CWnd::EnableWindow()の扱い方
-
ポインタについて
-
プーさんのマウスポインタを教...
-
連結リスト 要素の入れ替え
-
ハンドルはポインタか
-
C++で関数ポインタから関数名を...
-
自作DLLの引数について、ポイン...
-
NULLポインタが0でない処理系と...
-
TCHAR文字列内の検索について
おすすめ情報