この記事は、インテル® デベロッパー・ゾーンに公開されている「The Ultimate Question of Programming, Refactoring, and Everything」の日本語参考訳です。
26. 油断のならない VARIANT_BOOL
NAME プロジェクトから抜粋した以下のコードについて考えてみます。このコードにはエラーが含まれています。PVS-Studio アナライザーは、次の診断を出力します。
V721 The VARIANT_BOOL type is utilized incorrectly. The true value (VARIANT_TRUE) is defined as -1. Inspect the first argument. (V721 VARIANT_BOOL 型が正しく使用されていません。true 値 (VARIANT_TRUE) が -1 として定義されています。第 1 引数を確認してください。)
virtual HRESULT __stdcall put_HandleKeyboard (VARIANT_BOOL pVal) = 0; .... pController->put_HandleKeyboard(true);
説明
この問題に関連して、ウィットに富んだ引用があります。
We all truck around a kind of original sin from having learned Basic at an impressionable age. (我々は皆、多感な年代に Basic* を学んだことから、ある種の思い込みを持っています。)(C) P.J. Plauger
このヒントは、まさにこの問題を言い当てています。VARIANT_BOOL 型は、Visual Basic* の時代から使用されています (http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx)。今日のプログラミングの問題のいくつかは、この型に関連しています。この型では、”true” が -1 としてコーディングされています。
この型と true/false を示す定数の宣言を見てみます。
typedef short VARIANT_BOOL;
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#define VARIANT_FALSE ((VARIANT_BOOL)0)
一見、問題なさそうに見えます。false が 0 で、true が非ゼロです。-1 は、適切な定数と言えます。しかし、VARIANT_TRUE の代わりに、間違って true や TRUE を使用するミスが起こりやすいです。
正しいコード
pController->put_HandleKeyboard(VARIANT_TRUE);
推奨事項
不明な型がある場合は、すぐに作業に着手するのではなく、ドキュメントで確認します。型の名前に BOOL という単語が入っていても、この型の変数に 1 を配置できるとは限りません。
同様に、プログラマーは HRESULT 型を FALSE や TRUE と比較する際に、次のことを忘れることがあります。
#define S_OK ((HRESULT)0L) #define S_FALSE ((HRESULT)1L)
そのため、不慣れな型は、すぐにプログラミングに取り掛かるのではなく、慎重に扱うことを強く推奨します。
コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。