0

静的変数値に依存するコードを書きたいと思います。したがって、他の静的変数コンストラクターからこのコードを呼び出す可能性を排除するために、いくつかのチェックを追加したいと考えています。そして、静的な初期化順序の大失敗を一度だけ防ぎます。例えば:

static Foo foo = Foo();

// this function should be called ONLY from main program conrol flow
// ONLY after all static variable initialization was complete! ONLY!
int bar()
{
#ifdef _DEBUG
  if(! CRT_was_initialized_and_main_function_was_called ) ShowErrorMessage();
#endif
  if(foo.somefunction() == 2) return 0; else return -1;
}

//here inattentive programmer will caught error message during debug
const int barConstant = bar();

int main()
{
  //now all is fine
  const int barConstant = bar();
}

どうすればそうできますか?メイン関数が呼び出された後に関数が呼び出されたかどうかを確認する方法は?

更新: Foo オブジェクトには非常に重い初期化コードがあり、遅くなる可能性があり、例外をスローすることさえあります

更新 2: そうする生命の懸念はありません。ほとんどの場合、バー機能の前のコメントは正常に機能しました。これを手動で行うのではなく、プログラムのデバッグバージョンで不注意なプログラマーを罰するためのある種のデバッグチェックに興味があります。また、MSVC でのみ機能するクレイジーな組み込み関数の呼び出しのような非標準的な方法である可能性もあります。

4

5 に答える 5

3

boolmain が呼び出されたかどうかを示すグローバル フラグを作成します。最初は false です。内部main()で true に変更し、そこでのみ変更します。エレガントな解決策ではありませんが、非常に奇妙な問題の解決策でもあります。

于 2011-06-04T21:51:29.177 に答える
0

私はこの関数をmainCalled使用し、デフォルトでfalseであり、メインが呼び出されるたびにtrueに変更されるグローバルブール変数です:

int bar()
{
    static bool called = 0;
    if (!mainCalled)
        ShowErrorMessage();
    if (called)
    {
        return -1;
    }
    called = true;
    //do somthing
    return 0;
}
于 2011-06-04T21:46:46.387 に答える
0

int main_called = 0;関数の前にグローバル変数を宣言するだけです。

関数で変数が 0 かどうかを確認し、main で変数を 1 に設定します。

于 2011-06-04T21:47:25.893 に答える
0

これを行う移植可能な方法はありません。もちろん、メインで初期化し、メインの最後で初期化を解除する独自のグローバルを持つこともできます (例外がメインを終了した場合でも、これが正しく機能するように、コンストラクター/デストラクタを使用することを忘れないでください)。

MSVC では、#prgama init_seg を使用すると、より簡単ですが移植できません。これにより、3 つのプリセット フェーズが提供され、さらに多くのフェーズを自分で作成できます。

マーティン

于 2011-06-04T21:50:07.380 に答える
0

これは、独自の初期化をチェックできるシングルトン パターンの良い例ではないでしょうか?

于 2011-06-04T22:14:29.940 に答える