「offsetof()でnullポインタを減算する理由」の回答によると (そして私のK&Rの読み方)、C標準はそれを必要としません(size_t)((char *)0) == 0。それでも、整数型へのnullポインターのキャストが他の何かに評価される状況を見たことがありません。
コンパイラまたはシナリオがある場合(size_t)((char *)0) != 0、それは何ですか?
「offsetof()でnullポインタを減算する理由」の回答によると (そして私のK&Rの読み方)、C標準はそれを必要としません(size_t)((char *)0) == 0。それでも、整数型へのnullポインターのキャストが他の何かに評価される状況を見たことがありません。
コンパイラまたはシナリオがある場合(size_t)((char *)0) != 0、それは何ですか?
ご存知のように、特定のタイプのnullポインターの物理的表現は、必ずしもすべてゼロのビットパターンであるとは限りません。ポインター(任意のポインター)値を整数型に強制的に変換すると、結果は実装で定義されますが、通常(そしてそれが意図)、ポインターの数値(数値アドレス)は、可能であれば変更されません。これは、特定のプラットフォームで型のnullポインターがパターンchar *で表される0xBAADF00D場合(たとえば)、上記の式は0xBAADF00Dゼロではなく、と評価されることを意味します。もちろん、そのためには、ゼロ以外のnullポインターを備えたプラットフォームが必要です。私は個人的にそのようなプラットフォームで作業したことはありませんが、そのような実際のプラットフォームの数について聞いたことがあります(たとえば、組み込みプラットフォームの領域では、それは珍しいことではありません)。
さらに、補足として、異なるタイプのnullポインター値は、異なる物理的表現を持つ可能性があります。つまり、理論的には、、およびから異なる値を取得(size_t) ((int *) 0)でき(size_t) ((char *) 0)ます(size_t) ((double *) 0)。しかし、抽象的なC言語の観点からは完全に可能ですが、それはかなりエキゾチックな状況になります。
PSゼロ以外のnullポインターを持つ実際のプラットフォームの例については、こちら(C FAQ)をお読みください。
C標準でnullポインターの実行時表現に必要なのは、(6.3.2.3 / 3「ポインター」)だけです。
... nullポインターと呼ばれる結果のポインターは、任意のオブジェクトまたは関数へのポインターと等しくないことを比較することが保証されています。nullポインタを別のポインタ型に変換すると、その型のnullポインタが生成されます。
任意の2つのnullポインタは等しく比較されます。
しかし、あなたの質問は興味深いものです。個人的には、ランタイム値0を使用してnullポインターを表さないプラットフォームを知りません。ただし、標準ではそれが要求されていないので、コードでの仮定を回避できるのであれば、なぜでしょうか。
nullポインタにゼロ以外のランタイム値を使用するシステムを知っている人にも興味があります。
C99標準では、整数値0をポインターに変換すると、NULLポインターになるとされています。((char*)0)NULLポインタもそうです。NULLポインターは、の実際のバイナリ表現である必要はありません0。たとえば、次のようになります0x12345678。
C標準ではさらに、NULLポインターを整数定数に変換すると、結果は「実装定義」になると規定されています。AndreyTが言ったように、実際には、コンパイラーが行うことは、ポインターの数値を対応する整数値に使用することを単純にキャストすることです。したがって、上記の例では、整数値は最終的には何になる可能性がありますが0x12345678、技術的には何でもかまいません(つまり、コンパイラーは「NULLポインターを整数値に戻すと値になります」と言うことができます0xDEADBEEF)。これは、NULLポインターが値を持つプラットフォームでも0、コンパイラーが変換時に任意の整数値に変換できることを意味することに注意してください。ただし、実際には、かなり正気でないため、コンパイラはこれを行いません。
そうです、C標準は多くのことを許可しています。実際には、作業する可能性のあるプラットフォームはすべてNULLポインターを表し、NULLポインター0を整数値に変換すると結果がになり0ます。NULLポインタを使用しない(あいまいな)アーキテクチャのいくつかの例外のリストについては、ここ(セクション1.14)を参照してください。0
これはchar*Cにも適用されませんが、配列にインデックスを付けるスマートポインタクラスは、有効な配列インデックスであるため、NULLとして表すことを選択する場合があります。-10
のイディオムを考えるとmemset( my_new_struct, 0, sizeof my_new_struct );、デバッグ中心のシステムでさえ、そのアイデンティティを壊す可能性は低いです。