C でのグローバル初期化順序と依存関係の解決
C では、単一の翻訳単位内のグローバル変数は定義された順序で初期化されます。 。ただし、異なる翻訳単位にわたるグローバル変数の順序は明確に定義されていません。このあいまいさにより、次のコードに示すように、予期しない動作が発生する可能性があります。
<code class="cpp">struct Foo { Foo() { printf("Foo::Foo()\n"); } void add() { printf("Foo::add()\n"); } static int addToGlobal() { printf("Foo::addToGlobal() START\n"); globalFoo.add(); printf("Foo::addToGlobal() END\n"); return 0; } }; Foo globalFoo; int dummy = Foo::addToGlobal();</code>
globalFoo が初期化される前に addToGlobal が呼び出された場合、動作は予想どおりになります。
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
ただし、順序が逆になると、Foo のコンストラクターは呼び出されず、globalFoo は addToGlobal:
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
内で何らかの方法でアクセス可能になります。この動作は、グローバルの初期化順序がグローバル間の依存関係を無視するという事実に起因します。 。この場合、ダミーは globalFoo に依存しますが、その初期化順序は保証されません。
globalFoo を使用する前に Foo のコンストラクターが確実に呼び出されるようにするには、解決策の 1 つは、グローバル インスタンスへの静的ポインターを作成し、テストすることです。 addToGlobal 内で null かどうか。 null の場合、動的初期化の前にグローバル Foo が作成されます。
以上が異なる翻訳単位のグローバル変数が C で予期しない動作を引き起こす可能性があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。