次のコード(悪質なバグを含む)は、警告なしでGCCでコンパイルされます。しかし、もちろん、開発者(私)の期待どおりには機能しません。
#include <iostream>
struct A
{
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this-b; } // The bug is here: '-' instead of '->'
};
int main()
{
A a;
a.set(true);
std::cout << a.get() << std::endl; // Print 1
a.set(false);
std::cout << a.get() << std::endl; // Print 1 too...
return 0;
}
この種のタイプミスを避けるためにコンパイラー(GCC 4.8)に追加できる警告はありますか?
リンクされた質問:this->
を使用してメンバー変数/関数へのアクセスを強制(または警告)するオプションはありますか?
この特定の問題は、cppcheck
によって検出されます。
$ cppcheck --enable = all this-minus-bool.cxx this-minus-bool.cxxの確認... [this-minus-bool.cxx:7 ]:(警告)疑わしいポインターの減算。 '->'と書くつもりでしたか? (情報)Cppcheckはすべてのインクルードファイルを見つけることができません(詳細については--check-configを使用してください)
これには、インクルードパスが指定されていませんでした。 -I /usr/include/c++/4.8/
を追加しても、問題は検出されます。
checking this-minus-bool.cxx ... [this-minus-bool.cxx]:(情報)多すぎる#ifdef構成-cppcheckは45の構成のうち12のみを確認します。 --forceを使用して、すべての構成を確認します。 [this-minus-bool.cxx:7]:(警告)疑わしいポインターの減算。 「->」と書くつもりでしたか? [/ usr/include/c ++/4.8/bits/ostream.tcc:335]:(スタイル)Struct '__ptr_guard'には、1つの引数ではないコンストラクターがあります [/ usr/include/c ++/4.8/bits/locale_classes.tcc:248]:(エラー)割り当て解除されたポインターの割り当て解除:__c
そして、cppcheckは前述の#ifdef
構成でゆっくりと動作します。
(補足として、local_classes.tcc
のエラーは誤検知ですが、このツールは、このサイトのcatch
ブロックがマクロ__EXCEPTIONS
が設定されていない場合は入力しないでください。
免責事項:cppcheckの経験はありません。
番号、 this - b
は、this
がb
型であるにもかかわらず、ポインタbool
でポインタ演算を実行しています(b
は暗黙的にint
)。
(興味深いことに、always set this + b
は、b
がbool
型であるポインターへのポインターです。これは、スカラーの末尾を過ぎたポインターを設定できるためです。したがって、お気に入りのndefined behaviour spotterでも許可されます。)
配列の境界チェックは、常にC++プログラマの仕事でした。
また、あなたの場合、this
の使用は不要であることに注意してください。したがって、この過剰な使用を削減することは、問題を解決する1つの方法です。
@ arne-vogelが提案するcppcheck
以外の別のツールを提案します。警告を求める代わりに、より良い視覚補助を提供します。
clang-format を使用して、コードを自動的にフォーマットします。結果は次のようになり(設定によって異なります)、operator-
の周りに追加されたスペースによってバグがより見やすくなります。
struct A {
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this - b; }
};