web-dev-qa-db-ja.com

0x0の場所を指すポインターとNULLに設定されたポインターの違いは何ですか?

0x0000を指すポインターは、NULLに設定されたポインターと同じですか? C言語でNULL値が定義されている場合、物理的にどの場所に変換されるのですか? 0x0000と同じですか。これらの概念の詳細はどこにありますか?

12
Arpith

ここでの回答のほとんどが少なくとも明示的には対処していない点は、nullポインタは実行中に存在する値であり、nullポインター定数は、Cソースコードに存在する構文構造です。

nullポインター定数は、カールソンの答えが正しく述べているように、値が0の整数定数式(単純な_0_が最も一般的な例)などです。 _void*_にキャストされた式(_(void*)0_など)。

NULLはマクロであり、_<stddef.h>_および他のいくつかの標準ヘッダーで定義され、実装定義nullポインター定数に展開されます。展開は通常、_0_または_((void*)0)_のいずれかです(外側の括弧は他の言語規則を満たすために必要です)。

したがって、リテラル_0_は、ポインタ型の式を必要とするコンテキストで使用されると、alwaysは_null pointer_、つまり一意のポインタ値に評価されますそれはオブジェクトを指していません。これはではないnullポインタの表現について何かを意味します。ヌルポインターは、通常、すべてビット0として表されますが、何でも表すことができます。ただし、nullポインタが_0xDEADBEEF_として表されている場合でも、_0_または_(void*)0_はnullポインタ定数のままです。

この答え から stackoverflowに関する質問 はこれをうまくカバーしています。

これは、特に、メモリの領域をすべてビット0に設定できるmemset()またはcalloc()が、必ずしもその領域内のポインタをnullポインタに設定するとは限らないことを意味します。彼らはほとんどの実装でそうする可能性が高いですが、言語はそれを保証しません。

なぜこの質問が this one の複製と見なされないのか、またはここでどのように話題に上っているのかわかりません。

13
Keith Thompson

そこにあるすべてのプラットフォームは、自由にNULLを自由に定義できます。

C標準によると、ポインターにゼロを割り当てると、そのプラットフォームではNULL値に変換されます(ただし、そのプラットフォームでは)。そこにあるすべてのプラットフォームで。ただし、ほとんどのプラットフォームではゼロになります。

C言語仕様にあるものに関する情報。私が保証できない信頼性の情報源はこれです: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf

7
Mike Nakis

これはC言語で定義されています理由等しい1つの不変のマシンアドレスはありません。もしそうなら、それからの抽象化は必要ないでしょう!ほとんどのプラットフォームでは、NULLは最終的になんらかのタイプの0として実装される可能性がありますが、移植性を気にする場合は、これが普遍的にそうであると仮定するのは間違っています。

1
Kilian Foth

C標準ドキュメント セクション6.3.2.3によると:

値が0の整数定数式、またはvoid *型にキャストされた式は、nullポインター定数と呼ばれます。55)nullポインター定数がポインター型に変換された場合、nullポインターと呼ばれる結果のポインターはオブジェクトまたは関数へのポインタと等しくないことが保証されています。

これまでのところ、これから脱却したコンパイラを見たことがありません。

0
Karlson