0

設定されていないローカル変数を使用するとき、またはクラスまたは構造体のメンバーを初期化する前に直接アクセスするときに、いくつかの本当に明白なエラーをキャッチするのは非常に便利です。Visual Studio 2008 では、コンパイル時に「初期化されていないローカル変数が使用されています」という警告が表示され、デバッグ時にアクセス ポイントでランタイム チェック エラーが発生します。

ただし、関数の 1 つを介して初期化されていない構造体のメンバー変数にアクセスすると、警告やアサーションは発生しません。明らかに、最も簡単な解決策はそれをしないことですが、誰も完璧ではありません。

例えば:

struct Test
{
    float GetMember() const { return member; }
    float member;
};
Test test;
float f1 = test.member;      // Raises warning, asserts in VS debugger at runtime
float f2 = test.GetMember(); // No problem, just keeps on going

これは私を驚かせましたが、それはある程度理にかなっています.コンパイラは、未使用の構造体で関数を呼び出すことがエラーであると想定することはできません. そして、手の込んだものはすぐに他の多くの複雑さを引き起こすので、特にデバッグの助けとして、どの関数をいつ呼び出すことができるかを分類する必要はありません。クラス自体に独自のアサーションやエラー チェックを設定できることはわかっていますが、それによって単純な構造体が複雑になる可能性があります。

それでも、関数呼び出しのコンテキスト内のように見えますが、まだ初期化されていない内部GetMember()を認識していませんか? member実行中に発生することを考えると、静的なコンパイル時の控除に依存しているだけではないと想定しているRun-Time Check Failure #3ため、現在の私の理解に基づいて、同じチェックを適用するのが妥当であるように思われます。これは、この特定のコンパイラ/デバッガ (Visual Studio 2008) の単なる制限ですか、それとも C++ の動作に関連していますか?

4

1 に答える 1

2

おそらく、初期化されていないことに関する警告であることに気付くでしょうtest。これが、警告と実行時の失敗が行にのみ適用される理由です

float f1 = test.member;

これは未定義の動作につながり、少なくともデバッグ モードでは、MSVS は何らかのチェックを行い、クラッシュする可能性があります (リリースでは、バグはおそらく隠され、f1.

ただし、次の行は直接 UB にはなりません。f1読み取られず、そのデータ メンバーも (直接) 読み取られません。メソッドが呼び出され、コンパイラはメンバー関数が初期化されていないオブジェクトで UB を生成することを認識できません。この関数は、何かを画面に出力するだけで、メンバーを読み取らなくても問題ありません。コンパイラはコードを見ているので、理論的には知ることができますが、それほど深く掘り下げることはありません。静的コード アナライザーは、問題について警告する場合があります

于 2012-09-08T21:42:47.090 に答える