次のようなC++関数があるとします。
bool Foo(Bar* b)
{
if(b == nullptr) {
return false;
}
// Do stuff
return true;
}
さらに、C++ 03より新しい標準をサポートしていない一部のツールには制限があるため、ヘッダーに次のコードがあるとします。
#if __cplusplus <= 199711L
#define nullptr (0)
#include <stdint.h>
#else
#include <cstdint>
#endif // End if C++03
私のコンパイラは警告やエラーなしでこれをビルドします。私はnullptr
をキャストするhaveしていないことを知っていますが、私には説得力のある理由がありますすべきしますそれ?つまり、Foo()
を使用するとif (b == static_cast<Bar*>(nullptr))
を使用すると回避できたおよびコンパイラが警告しなかったいくつかのバグが潜む可能性がありますか私について(C++ 03またはC++ 11以降)
キャストを避ける理由は次のとおりです。
nullptr
を使用するたびにキャストを追加すると、コードが乱雑になり、読みにくくなります。番号2はそれ自体は正当な理由ではないので、コードの作成者にとってより便利なためか、そうする必要がある理由が本当にないためにそうなったのかと思います。
提案された回答に基づいて編集:質問は次のとおりです。
NULL
を整数値に設定し、すべてのそれに伴う慣行?#define NULL (0)
の種類に行き詰まっている場合、常にキャストを適用する必要がありますか?例:if(b == static_cast<Bar*>(NULL))
はあまり実行されていないようで、これが怠惰なのか、または比較の際にこれを実行するか、実行しない理由があるのかと疑問に思っています(上記のヌルポインターチェックのように)。さらに、C++ 03より新しい標準をサポートしていない一部のツールには制限があるため、ヘッダーに次のコードがあるとします。
これは非常に悪い考えです。
式_(0)
_は、(多かれ少なかれ)NULL
のC++定義と同等です。問題は、nullptr
はNULL
の欠点に対処するために特別に開発されたということです。
したがって、それらが何らかの形で同等であると偽ると、読者は混乱するだけです。 C++ 03コンパイラでコンパイルすると、動作が異なるコードをC++ 11に慣れている人々にそれを提供します。例えば:
_void foo(int);
void foo(Bar*);
foo(nullptr);
_
C++ 11は、これがmust call foo(Bar*)
であることを通知します。ただし、C++ 03マクロは代わりにfoo(int)
を呼び出します。 foo(NULL)
でも同じ問題が発生するため、nullptr
はそれを阻止するために開発されました。
つまり、C++ 03コードにのように見える C++ 11コードがあるが、-動作が異なるのはひどい考えです。
nullptr
、設計上、特定のポインター型にキャストする必要はほとんどありません。唯一の例外は、次のようなフォームの関数を呼び出す場合です。
_template<typename T>
void foo(T* p);
_
ただし、その場合でも、foo<ActualType>(nullptr)
を使用するだけで、foo(static_cast<ActualType*>(nullptr))
と同じ効果を得ることができます。
Not -nullptr
は、NULL
と同じ状況でキャストする必要があります。実際、これは基本的にNULL
と同等であるため、NULL
を使用する必要があります。したがって、NULL
が持っているすべての警告があります。
そして参考までに:C++ 11の_nullptr_t
_型と同じ動作をする型をC++ 03で作成することはほとんど不可能です。暗黙の変換などを使用して、接近することができます。しかし、それがうまくいかない場合は常にあります。
したがって、確実ではないnullptr
の有望な動作を停止します。