初期化されていないクラス メンバー変数を簡単に見つける方法を探しています。
実行時またはコンパイル時のいずれかでそれらを見つけることは問題ありません。
現在、クラス コンストラクターにブレークポイントがあり、メンバー変数を 1 つずつ調べています。
初期化されていないクラス メンバー変数を簡単に見つける方法を探しています。
実行時またはコンパイル時のいずれかでそれらを見つけることは問題ありません。
現在、クラス コンストラクターにブレークポイントがあり、メンバー変数を 1 つずつ調べています。
GCCを使用する場合は、-Weffc++
フラグを使用できます。このフラグは、メンバー初期化リストで変数が初期化されていない場合に警告を生成します。これ:
class Foo
{
int v;
Foo() {}
};
につながる:
$ g++ -c -Weffc++ foo.cpp -o foo.o
foo.cpp: In constructor ‘Foo::Foo()’:
foo.cpp:4: warning: ‘Foo::v’ should be initialized in the member initialization list
欠点の1つは-Weffc++
、変数に適切なデフォルトコンストラクターがあり、初期化が不要な場合にも警告が表示されることです。また、コンストラクターで変数を初期化するときに警告が表示されますが、メンバー初期化リストには警告が表示されません。-Weffc++
また、コピーコンストラクターの欠落など、他の多くのC ++スタイルの問題について警告するため、定期的に使用する場合は、コードを少しクリーンアップする必要があります。
匿名ユニオンを使用すると常に警告が表示されるバグもあります。これは現在、他の方法では回避できず、警告をオフにすることができます。これは次の方法で実行できます。
#pragma GCC diagnostic ignored "-Weffc++"
ただし、全体として-Weffc++
、C++でよくある多くの間違いを見つけるのに非常に役立つことがわかりました。
cppcheckはこれを見つけます。例:
cppcheck my_src_dir --output-file=check.txt --inconclusive --enable=warning
Valgrindは、Linux を使用しているかどうかを教えてくれます。
-Wuninitialized
?
(これは、変数が初期化されていない状態で使用されているかどうかのみをチェックします。
struct Q {
int x, y;
Q() : x(2) {}
int get_xy() const { return x*y; }
};
get_xy()
g++ は、ユーザーがに代入せずに呼び出した場合にのみ警告しy
ます。)
Visual Studio (MSVC) には /sdl (追加のセキュリティ チェックを有効にする) コンパイラ オプションがあります ( http://msdn.microsoft.com/en-us/library/jj161081.aspx )。実行時に、それは:
クラス メンバーの初期化を実行します。オブジェクトのインスタンス化 (コンストラクターの実行前) で、ポインター型のクラス メンバーを自動的にゼロに初期化します。これは、コンストラクターが明示的に初期化しないクラス メンバーに関連付けられた初期化されていないデータの使用を防ぐのに役立ちます。
これは、コンパイル時に初期化されていないメンバー変数を検出するのに役立ちませんが、実行時に発生したときの動作をより予測しやすくします。もちろん、このオプションが有効になっていることに依存するコードを書くべきではありません。
Visual Studio を使用している場合は、デバッグ モードでコンパイルし、デバッガーでプログラムを停止して、0xCC (スタック) または 0xCD (ヒープ) を含むバイトに初期化されている変数を探すことができます。
個人的には、より徹底的なアプローチのために静的分析ツールに投資したいと思います。
/Visual Studio で分析(「チーム システム」)
注意してください!ここで提案されているコンパイラ オプションは、信頼できるものでも、バージョンに依存しないものでもありません。簡単な例を考えてみましょう:
class A {
int a;
public:
void mA() {
printf("haha");
++a;
int g = 2/a;
printf("%i\n",g);
}
};
int main() {
A a;
a.mA();
}
このことでコンパイルされたものは、4.6 までの gcc バージョンg++ -O3 -Weffc++ -Wuninitialized
について報告uninitialized
し、4.7 および 4.8 (MacPorts でテスト済み) で問題なく合格します。次に、奇妙なことに、 を削除するprintf("haha");
と、4.7 と 4.8 の両方で突然 が表示されuninitialized A::a
ます。初期化されていない vars にClang
(convenient の代わりに) どうにかしてゴミを割り当てるので、少し良くなります。0
A::a
上記のいずれかで初期化されていないものを見つけるのはあまり運がありませんでしたvalgrind
。おそらく、紳士の提案valgrind
は、このエラーを見つけるための適切なオプションを提供する可能性があります.
結論: 素晴らしい質問ですが、現時点では信頼できる解決策はあまりありません... (私の見方では)。
これは、clang-analyze を使用した Clang で実行できます。未使用の変数がいつアクセスされるかを示す素敵な HTML レポートを作成します。
次のコードを検討してください
unint.cpp:
int main()
{
int a;
int b;
a++;
b = b + 5;
return 0;
}
以下のコメントでコードをコンパイルすると、警告メッセージが表示されます。
g++ -O3 -Wuninitialized unint.cpp
注: -Wuninitialized には -O3 オプションも必要です。