CでNULL
が常にfalseに変換されると仮定しても安全ですか?
void *somePtr = NULL;
if (!somePtr) {
/* This will always be executed? */
}
または、NULL
の値に対して明示的なチェックを行う必要がありますか?
はい。 Cはゼロ以外の値を真、ゼロ値を偽とみなすため、NULLは偽と評価されます。 NULLは基本的にzero
アドレスであり、比較ではそのように扱われます。ブールチェックのためにintに昇格されると思います。私はおそらくチェックを明示的にするだろうが、Cに精通している人なら誰でもあなたのコードが読めると期待するだろう。
CおよびC++プログラミングでは、2つのNULLポインターが等しいことを保証されます。 ANSI Cは、整数型との比較でNULLポインターが0に等しいことを保証します。さらに、マクロNULLはNULLポインター定数、つまり値0(整数型として、またはvoidへのポインターに変換)として定義されているため、NULLポインターはNULLと等しくなります。
何を想定しても安全ではありません。
また、テスト対象について明示的なチェックを行うとより明確になります。
「C」言語は、(void *)0が実際に有効なポインターになる可能性のある時代からのものです。 8080およびZ80マイクロプロセッサのアドレス0に割り込みベクトルがありました。そのようなアーキテクチャの選択に直面して、ヘッダーファイルにNULLの値を宣言させる以外に何もできませんでした。 NULLが(void *)0(0xffffが次の代替手段)に等しくないため、if()ステートメントに未定義の動作を与えるいくつかのコンパイラーがあります。
C++はこれに慈悲深く終止符を打ち、ヌルポインターは0から割り当て可能であり、0に対してテスト可能です。
はい(少なくとも標準に準拠したCコンパイラの場合!)
comp.lang.c FAQ から:
Q:NULL以外のポインターをテストするための短縮ポインター比較「if(p)」は有効ですか? nullポインターの内部表現がゼロ以外の場合はどうなりますか?
A:常に有効です。
NULLは単なるプリプロセッサ定義です。 stdio.hにあります。通常、非常識な人だけがそれを再定義しますが、それは可能です。例:
#include <stdio.h>
#ifdef NULL
#undef NULL
#define NULL 1
#endif
void main()
{
if (NULL)
printf("NULL is true\n");
else
printf("NULL is false\n");
}
このコードは「NULL is true」を出力します。あなたが私を信じないなら、それを試してください。あなたのコンパイラは、あなたが何かおかしなことをしているという警告さえしないかもしれません。
C-FAQの 質問5. を参照するだけです。この正確な質問に答えます。
NULL
は、メモリ内の役に立たない/存在しない場所を指すことが保証されている定数ポインタとして定義されています。 NULL
のほとんどの実装は((void *)0)
しかし、そうである必要はありません。
はい、ほとんど。
まず、NULLはtypedefです。以前に含まれていたヘッダーで言うことで、私はあなたを大いに混乱させることができました
_#define NULL 1
_
これはあまり意味がないかもしれませんが、いつから他の人のコードが意味をなしたのでしょうか? :)
また、おそらく構文的には安全ですが、意味的には正しくありません。 NULLは「何もない」ことを意味し、trueまたはfalse、ブール値、intまたはstringのいずれでもありません。それは「無のための象徴」を意味します。 NULLのテストは哲学的な問題に似ています。木が森に落ち、if(listener)
の場合、音がしますか?
みなさんにお願いし、NULLに対するテストについて明確にしてください。