• ベストアンサー

「NULLポインタ」と「演算の結果としてのアドレス0」との比較

ものすごく基本的な疑問です。。。 「C言語FAQ日本語訳」http://www.kouno.jp/home/c_faq/ ここの「05.ヌルポインター」を見ると以下のような意味の記述があります。 「NULLポインタは他のどんなポインタの値とも区別可能で、有効なポインタと比較しても等しくなる事はない」 「ポインタを書くべき場所に書かれた定数0はコンパイル時にNULLポインタに変換される」 そこで以下のプログラムを Borland C++ 5.5 for Win32 でコンパイル・実行してみたところ、 p1 == p2 とりました。これって変ですよね? p1 は明示的に定数0で初期化しているのでNULLポインタですが、p2 は演算の結果としてアドレス0番地を指しているので、NULLポインタでは無いですよね? これはコンパイラが間違っていると思って良いのでしょうか? #include <stdio.h> int main() { char *p1,*p2; p1 = 0; p2 = (char *)1; p2--; if(p1 == p2){ printf("p1 == p2"); } else{ printf("p1 != p2"); } return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

規格上, 整数型からポインタに変換してよいのは次の 2つの場合に限られます: 1.もともとポインタであった値を十分な大きさの整数型に変換しており, それを元と互換なポインタ型に再度変換する場合. 2.整数型の値が定数の 0 であった場合. これ以外の処理を行うようなプログラムは ill-formed であり, その動作は undefined である (= 規格はその動作について見放す) と規定されています. 従って示されたプログラムがどのように動作したとしても規格は一切関知しません. ちなみに NULL ポインタと「アドレスの 0番地」は全く無関係です>#1 の人

min_will
質問者

お礼

ありがとうございます。 納得です。 規格に沿った方法で0番地を指すポインタを得る事は出来ないということですね。

その他の回答 (2)

  • shige_70
  • ベストアンサー率17% (168/946)
回答No.2

K&Rに以下の記述があります(プログラミング言語C第2版 124ページより抜粋) 『Cでは、データを正しく指すポインタは0にはならないことを保証している』 すなわち、ご質問に書かれたプログラムの変数p2は『データを正しく指していない』のです。 つまり、プログラムが間違っているのです。 そもそも、よほど特殊な事情がない限り、ポインタ変数に絶対アドレスを代入するようなことはしてはいけません。

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.1

>p2 は演算の結果としてアドレス0番地を指しているので アドレス0番地というのがそもそも「有効なポインタ」ではありません。「アドレス0番地==NULL」だということだと思います。

関連するQ&A