使用しているハードウェアインターフェイスのC++コードの例をいくつか見ていて、次の行に沿って多くのステートメントがあることに気づきました。
if ( NULL == pMsg ) return rv;
定数を最初に置くのは良い考えだと人々が言うのを聞いたことがあると思いますが、それはなぜですか?大きなステートメントがある場合、比較対象をすばやく確認できるようにするためですか、それともそれ以上のものがあるのでしょうか。
比較(==)と割り当て(=)を混在させないようにします。
ご存知のように、定数に割り当てることはできません。試してみると、コンパイラーはエラーを出します。
基本的に、これは防御的なプログラミング手法の1つです。自分から身を守るため。
あなたが書くのを止めるには:
if ( pMsg = NULL ) return rv;
間違って。ただし、優れたコンパイラはこれについて警告するので、ほとんどの人は読みにくいと感じるため、「定数優先」の方法を使用しません。
私がいくつかのコメントに書いたことを明確にするために、ここに理由がありますnot C++コードでこれを行う。
たとえば、誰かが文字列クラスを作成し、キャスト演算子をconst char*
に追加することにしました。
class BadString
{
public:
BadString(const char* s) : mStr(s) { }
operator const char*() const { return mStr.c_str(); }
bool operator==(const BadString& s) { return mStr == s.mStr; }
// Other stuff...
private:
std::string mStr;
};
今、誰かが盲目的にconstant == variable
「防御的」プログラミングパターンを適用します。
BadString s("foo");
if ("foo" == s) // Oops. This compares pointers and is never true.
{
// ...
}
これは、IMOであり、誤った割り当てよりも陰湿な問題です。コールサイトからは、明らかに何かが間違っていることがわからないためです。
もちろん、本当の教訓は次のとおりです。
ただし、制御できないサードパーティのAPIを扱っている場合もあります。たとえば、WindowsCOMプログラミングで一般的な_bstr_t
文字列クラスには、この欠陥があります。
シングル=割り当てのバグを停止します。
例えば、
if ( NULL = pMsg ) return rv;
コンパイルされませんが、
if ( pMsg = NULL) return rv;
コンパイルして頭痛の種になります
定数が最初の場合、定数に値を割り当てることは違法であるため、誤って=
ではなく==
を書き込んだ場合にコンパイラーは警告を出します。
彼らは、「割り当てと比較の混合を防ぐために」と言いました。
実際には、それはナンセンスだと思います。もしあなたがso左側に定数を置くことを忘れないように訓練されているなら、あなた間違いなく混同しないでしょう '= 'と' == '、あなたは? ;)
警告を出力するコンパイラは優れていますが、現実の世界では、警告をエラーとして扱う余裕がない人もいます。変数と定数の順序を逆にすると、この単純なスリップが常にエラーとして表示され、コンパイルが妨げられます。このパターンにすぐに慣れ、それが保護するバグは微妙なものであり、一度導入すると見つけるのが難しいことがよくあります。
記事を忘れましたが、引用は次のようになりました。「== ";))を使用することを覚えているよりも、定数を最初に置くことを覚えている方が明らかに簡単です。