52

初期化されていないクラス メンバー変数を簡単に見つける方法を探しています。

実行時またはコンパイル時のいずれかでそれらを見つけることは問題ありません。

現在、クラス コンストラクターにブレークポイントがあり、メンバー変数を 1 つずつ調べています。

4

11 に答える 11

32

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++でよくある多くの間違いを見つけるのに非常に役立つことがわかりました。

于 2010-05-26T09:42:58.873 に答える
11

cppcheckはこれを見つけます。例:

cppcheck my_src_dir --output-file=check.txt --inconclusive --enable=warning
于 2011-04-11T19:09:39.637 に答える
10

Valgrind ( Linux ではFREE ) とPurify (Windows では) は、特別な仮想マシンでコードを実行することにより、初期化されていない変数、無効なポインターなどを見つけます。

これは使いやすく、非常に強力です。明らかな初期化されていない変数以外にも、多くのバグが見つかる可能性があります。

CoverityKlocwork、およびLintは、静的コード分析を使用して、初期化されていない変数を見つけることができます。

于 2010-01-20T08:14:14.757 に答える
9

Valgrindは、Linux を使用しているかどうかを教えてくれます。

于 2010-01-20T08:10:07.397 に答える
7

-Wuninitialized?

(これは、変数が初期化されていない状態で使用されているかどうかのみをチェックします。

struct Q { 
  int x, y;
  Q() : x(2) {}
  int get_xy() const { return x*y; }
};

get_xy()g++ は、ユーザーがに代入せずに呼び出した場合にのみ警告しyます。)

于 2010-01-20T07:35:34.653 に答える
5

Visual Studio (MSVC) には /sdl (追加のセキュリティ チェックを有効にする) コンパイラ オプションがあります ( http://msdn.microsoft.com/en-us/library/jj161081.aspx )。実行時に、それは:

クラス メンバーの初期化を実行します。オブジェクトのインスタンス化 (コンストラクターの実行前) で、ポインター型のクラス メンバーを自動的にゼロに初期化します。これは、コンストラクターが明示的に初期化しないクラス メンバーに関連付けられた初期化されていないデータの使用を防ぐのに役立ちます。

これは、コンパイル時に初期化されていないメンバー変数を検出するのに役立ちませんが、実行時に発生したときの動作をより予測しやすくします。もちろん、このオプションが有効になっていることに依存するコードを書くべきではありません。

于 2014-10-12T10:08:48.747 に答える
4

Visual Studio を使用している場合は、デバッグ モードでコンパイルし、デバッガーでプログラムを停止して、0xCC (スタック) または 0xCD (ヒープ) を含むバイトに初期化されている変数を探すことができます。

個人的には、より徹底的なアプローチのために静的分析ツールに投資したいと思います。

于 2010-01-20T11:02:19.590 に答える
2

/Visual Studio で分析(「チーム システム」)

于 2010-01-20T15:30:51.300 に答える
0

注意してください!ここで提案されているコンパイラ オプションは、信頼できるものでも、バージョンに依存しないものでもありません。簡単な例を考えてみましょう:

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は、このエラーを見つけるための適切なオプションを提供する可能性があります.

結論: 素晴らしい質問ですが、現時点では信頼できる解決策はあまりありません... (私の見方では)。

于 2013-06-21T10:17:07.893 に答える
0

これは、clang-analyze を使用した Clang で実行できます。未使用の変数がいつアクセスされるかを示す素敵な HTML レポートを作成します。

于 2016-06-11T15:11:15.993 に答える
-2

次のコードを検討してください

unint.cpp:

int main()
{
    int a;
    int b;
    a++;
    b = b + 5;

    return 0;
}

以下のコメントでコードをコンパイルすると、警告メッセージが表示されます。

g++ -O3 -Wuninitialized unint.cpp

注: -Wuninitialized には -O3 オプションも必要です。

于 2013-04-25T11:02:24.790 に答える