'NULL' をブール データ型に割り当てることは許容されますか?
13 に答える
理論的な観点からは、はい。しかし、それは恐ろしいことです。
NULL
ポインターが何も指さないようにするためにポインターに割り当てられるヌルポインター定数です。
...
ptr = NULL; // now it points to no object anymore
...
// or ptr == 0
if(ptr == NULL) {
...
}
いずれにせよ興味がある場合は、標準への参照を次に示します。まず、ヌルポインタ定数は ( 4.10/1
)
null ポインター定数は、0 に評価される整数型の整数定数式 (5.19) 右辺値です。
では、null ポインター定数を に変換するとどうなるbool
でしょうか。で説明されてい4.12/1
ます:
算術、列挙、ポインター、またはメンバー型へのポインターの右辺値は、bool 型の右辺値に変換できます。ゼロ値、NULL ポインター値、または NULL メンバー ポインター値は false に変換されます。a
(それについて話すとき、それはrvalue
本質的にその型の変数ではなく単純な値を意味します)。
さて、それは実際にはNULL
何ですか?読み取り18.1/4
(C では、null ポインター定数の定義が異なることに注意してください。これが、C++ を明示的に参照する理由である可能性があります)
マクロ NULL は、この国際標準の実装定義の C++ ヌル ポインター定数です。
その組み合わせの重要な部分は「A zero value ... is converted to false
」の部分です。NULL
bool 変数への代入はNULL
、boolean 値への変換を試みます。上記の箇所で述べられているように、そのような変換は存在し、行うことができます。
null pointer
null ポインターについて理解すべきもう 1 つの重要な点は、 aと aの違いnull pointer constant
です。先ほど読んだように、null ポインター定数はゼロの整数値です。ただし、 anull pointer
とその値 anull pointer value
はポインターであり、その型はポインター型です。以下は int 型でヌルポインタ定数です
#define NULL ('n'-'n') // looks suspicious, but conforms
これは、値がゼロの整数定数式 (つまり、コンパイル時に既知の整数値) であるためです。以下はヌルポインタ値です
(void*)NULL
ただし、null ポインター定数ではありません。とにかく、上記の引用が示すように、null ポインター値も bool に変換されます: " A .. null pointer value .. is converted to false
"。だから皆さん元気です。
n2798 の私のコピーから:
18.1 タイプ
3 マクロ NULL は、この国際標準 (4.10) における実装定義の C++ NULL ポインター定数です。
と
4.12 ブール変換 [conv.bool]
1 算術、スコープなし列挙、ポインター、またはメンバー型へのポインターの右辺値は、bool 型の右辺値に変換できます。ゼロ値、ヌル ポインター値、またはヌル メンバー ポインター値は false に変換されます。その他の値は true に変換されます。std::nullptr_t 型の右辺値は bool 型の右辺値に変換できます。結果の値は false です。
だから、はい、それができる可能性が高いようです。
NULL は通常 0 のプリプロセッサ #define であり、0 は NULL および false のポインター表現に変換可能であるため、コンパイラーはそれを拒否しません。
私の意見では、これによりコードの可読性が低下しますが、必要に応じて確認してください。NULL は結局のところ 0 です。
これが技術的に可能であっても、私はそれを避けます。null 値が必要な場合は、ブール値とは異なるデータ型にモデル化する必要があるようです。
ブール値を使用する場合は、モジュールとコードを設計どおりに使用するように適切に設計してください。3 つではなく 2 つの潜在的な値を使用してください。3 つ必要な場合は、int や string などの別のデータ型を使用し、3 つの値のそれぞれが何かを意味するようにします (string では、null string は null を意味します)。
ポインターはブール値のコンテキストで使用できるように設計されているため、一般的には機能します。
int *i = NULL;
if (i) // This is a pretty acceptable use of pointer conversions to bool
{
// never runs.
}
また
int *i = NULL;
...
bool b = i; // Maybe not so terrible, but you're better off just assigning to a pointer.
これは、この使用を許可するために意図的に行われます (標準リファレンスについては、dirkgently の回答を参照してください)。この構文を使用している場合:
bool i = NULL; // Don't do this
bool i2 = 0; // better
bool i3 = false; // Best
その場合、おそらく誤解を招く可能性がありますが、移植可能で予測可能な方法で機能します。NULL が 0 と定義されている場合は false の値を取得するか、NULL が本当に NULL ポインターである場合は false と評価されます。
いいえ、「ファイルが見つかりません」という専門用語を使用する必要があります。
編集:
参照: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
適切な答えは No です。
あなたがやろうとしていると思うのは、NULLを使用して「初期化されていない」または「まだ知られていない」という意味です。これは通常、データベースでは機能しますが、コードでは常に機能するとは限りません。NULL の定義は、プリプロセッサごと、言語ごとに異なるためです。
ブール値は、定義上、2 状態の値です。それらを 3 状態値として使用しようとするとエラーになります。せいぜいこれは将来的に他の開発者に混乱を引き起こす汚いハックです。
なぜあなたがそれをしたいのかわかりません。初期化しようとしている場合は、0 を使用してください。MSN が述べたように、コンパイラはそれを拒否しません。おそらく、最初に bool を NULL に設定する理由を説明する必要がありますか?
それはできますが、意味がわかりません。あなたが持っていると仮定します:
void* p = NULL;
bool b = p;
次のように書いてみませんか?
void* p = NULL;
bool b = (p != NULL);
より明確で、適切なコンパイラーは同じコードを生成します。
NULL
C ++では、手段Empty pointer
、またはそれ\0
を「ゼロポインター」、「何もない」などと呼びます。
しかし、すべて:それは数字0
です-「ゼロ」。
bool の 0 は、false
受け入れられることを意味します。
しかし、時々あなたが望まないかもしれないように設定bool
するNULL
:あなたが特別なブール値を含むようにしたい場合 //true
とfalse
呼ばundefine
れる値3-state Boolean
。
false が 0 のままで、NULL が 0 に定義されている限り、はい、ただし、これは将来変更される可能性があります。概念が混ざり合って明確さが失われるため、悪い習慣だと思います。
NULL は通常 0(void*)0
ではなく であるため、この場合 NULL はポインターであるため、C++ ではそのようには機能しません。明示的なキャストを行う必要があります: reinterpret_cast<bool>(NULL)
、いいえ、これはきれいではありません。true
/1
とfalse
/を使用する必要があります0
NULL は定義上 0 ではありません。私は知りませんが、NULL にゼロ以外の値を使用したり、アドレスの背後にあるサンクにフラグを設定したりするコンパイラがいくつかある可能性があります。あなたのコードが 1 つに移植されるのは運がいいだけです。結果として生じるバグを修正しなければならないのは、私の運だけです。
だから私は「いいえ、それは受け入れられません」と言います。