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

その他インテル® DPC++/C++ コンパイラー特集

この記事は、インテル® デベロッパー・ゾーンに公開されている「The Ultimate Question of Programming, Refactoring, and Everything」の日本語参考訳です。


9. 終端 null 文字には ‘\0’ を使用する

Notepad++ プロジェクトから抜粋した以下のコードについて考えてみます。このエラーは、次の PVS-Studio 診断によって検出されます。

V528 It is odd that pointer to ‘char’ type is compared with the ‘\0’ value. Probably meant: *headerM != ‘\0’. (V528 ‘char’ 型へのポインターが ‘\0’ 値と比較されています。*headerM != ‘\0’ の間違いだと考えられます。)

TCHAR headerM[headerSize] = TEXT("");
...
size_t Printer::doPrint(bool justDoIt)
{
  ...
  if (headerM != '\0')
  ...
}

説明

この例では、終端 null (英語) 文字に ‘\0’ が使用されているため、エラーを簡単に見つけて修正できます。しかし、もしコードが次のように記述されていたらどうでしょうか?

if (headerM != 0)

配列アドレスは 0 と比較され、結果は常に true になります。この場合、エラーなのか、冗長なチェックなのか判断しかねます。特に、別のプログラマーが記述したコードやずっと前に記述されたコードではなおさらです。

この例では、’\0′ が使用されているため、プログラマーは 1 文字の値をチェックしたいのだと推測できます。また、headerM ポインターと NULL の比較は意味がないことも分かっています。これらすべてを考慮して、文字列が空かどうかチェックしようとして、プログラマーが間違ったコードを記述したことを推測できます。このコードを修正するには、ポインターの逆参照を追加する必要があります。

正しいコード

TCHAR headerM[headerSize] = TEXT("");
...
size_t Printer::doPrint(bool justDoIt)
{
  ...
  if (*headerM != _T('\0'))
  ...
}

推奨事項

0 は、NULLfalse、null 文字 ‘\0’、または数値 0 を指す可能性があります。そのため、面倒がらずに、常に短縮形の 0 は使用しないようにします。短縮形の 0 は、コードを分かりづらくし、エラーを見つけにくくします。

次の表記を使用します。

  • 0 – 整数のゼロに使用
  • nullptr – null ポインタ―に使用 (C++)
  • NULL – null ポインターに使用 (C)
  • ‘\0’、L’\0’、_T(‘\0’) – 終端 null に使用
  • 0.0、0.0f – 浮動小数点型のゼロに使用
  • false、FALSE – ‘false’ 値に使用

この規則に従うことで、コードが分かりやすくなり、コードレビュー時に不具合を見つけやすくなります。

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

タイトルとURLをコピーしました