ホームページ  >  記事  >  バックエンド開発  >  異なる翻訳単位のグローバル変数が C で予期しない動作を引き起こす可能性があるのはなぜですか?

異なる翻訳単位のグローバル変数が C で予期しない動作を引き起こす可能性があるのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-30 02:51:28947ブラウズ

 Why Can Global Variables in Different Translation Units Lead to Unexpected Behavior in C  ?

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。