プログラミング、リファクタリング、そしてすべてにおける究極の疑問: No. 26

同カテゴリーの次の記事

インテル® ソフトウェア・ツールにおける浮動小数点結果の再現性

この記事は、インテル® デベロッパー・ゾーンに公開されている「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* の時代から使用されています (英語)。今日のプログラミングの問題のいくつかは、この型に関連しています。この型では、”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 の代わりに、間違って trueTRUE を使用するミスが起こりやすいです。

正しいコード

pController->put_HandleKeyboard(VARIANT_TRUE);

推奨事項

不明な型がある場合は、すぐに作業に着手するのではなく、ドキュメントで確認します。型の名前に BOOL という単語が入っていても、この型の変数に 1 を配置できるとは限りません。

同様に、プログラマーは HRESULT 型を FALSETRUE と比較する際に、次のことを忘れることがあります。

#define S_OK     ((HRESULT)0L)
#define S_FALSE  ((HRESULT)1L)

そのため、不慣れな型は、すぐにプログラミングに取り掛かるのではなく、慎重に扱うことを強く推奨します。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事