これ:
int* p = nullptr;
auto tmp = *p;
gcc4.6もVS2010sp1も少なくとも警告を発行しません。これらのコンパイラのいずれかに、このような場合に警告を発行させるオプションはありますか?/w4を使用してVSでテストコンパイルしました。
これ:
int* p = nullptr;
auto tmp = *p;
gcc4.6もVS2010sp1も少なくとも警告を発行しません。これらのコンパイラのいずれかに、このような場合に警告を発行させるオプションはありますか?/w4を使用してVSでテストコンパイルしました。
違法ではなく、未定義の動作です。
これに対する警告をオンにすると、誤った安心感が生じる可能性があります。これは、一部のポインターnullptr
が何かを指しているか、または別のものを指しているかどうかが実行時までわからないことが多いためです。Valgrind は、これらのエラー (およびその他のエラー) をチェックできます。
言うまでもなく、コンパイル時間が劇的に増加します。
Visual Studio 2010 SP1 (必要なエディションがわからない) で、コード分析を実行します。正確なコードを試してみたところ、警告 6011 が表示されます。
warning C6011: NULL-Zeiger "p" wird dereferenziert.: Lines: 138, 139
「このようなケース」は非常にあいまいであり、コンパイラがすべての逆参照からバックトラックし、ポインターが定数で無効な値を持っていることを知っていることを証明できるかどうかを確認する必要があります。
プログラムの他の部分にポインターへのポインターが与えられ (エイリアシング)、別のコード パスで、または (さらに悪いことに) 別のスレッドで上書きされる可能性があると考えてください。
検出するのは簡単ではありません。実際のプログラムのコンパイル時間に関するコストは、妥当な量の労力で実装できたとしても、それほど価値がないと思います。
valgrind はこれを指摘できます。私はこれを使用して、この種のあいまいなケースと無効な読み取り/書き込みをチェックします。
これは実行時エラーであり、コンパイル時エラーではありません。コンパイラーは、ポインター値について完全に確信できる非常に限られた場合にのみ、そのような逆参照をキャッチできます。複雑さを増す意味はありません。
これは未定義の動作です。つまり、コンパイラは警告やエラーを発行する必要はありません。
null ポインターの逆参照は未定義の動作です。コンパイラはそのようなケースを診断できますが、必須ではありません。