10

グローバル変数は同じコンパイル単位の宣言順序で作成され、作成順序は複数のコンパイル単位間で定義されていないことを知っています。

グローバル変数は、それらが定義されているコンパイルユニットからのコードが呼び出される前に作成されることを少し前に読みました。これは規格で定義されていますか?

例:

file1.cpp

int f1v1 = f1_1();
int f1v2 = f1_2();

void f1(){...}

int f1_1(){...}
int f1_2(){...}

file2.cpp

static int f2v1 = f2_1();
static int f2v2 = f2_2();

int f2_1(){...}
int f2_2(){...}

main.cpp

#include "file1.h"
#include "file2.h"

int main()
{
    f1();

    return 0;
}

この場合、前後にf1_1()呼び出される標準によって保証されていますか?file2.cppで定義された関数が呼び出されず、file2.cppの外部に表示されないため、およびがまったく呼び出されないことが標準によって保証されていますか?f1_2()f1()f2_1()f2_2()f2v1f2v2

編集:

file1.cppがlib1でコンパイルされ、file2.cppがlib2でコンパイルされる場合の動作は、標準で指定されていますか?

4

2 に答える 2

4

[basic.start.init]に基づく:

f1_1()前に実行することが保証されていf1_2()ます(第2項:「単一の変換ユニット内で定義された順序付き初期化を持つ変数は、変換ユニット内で定義された順序で初期化されるものとします。」)。

両方とも前に実行されることが保証されてf1()います(para.4: "初期化がmainの最初のステートメントの後のある時点まで延期される場合、それは同じで定義された関数または変数の最初のodr-use(3.2)の前に発生するものとします初期化する変数としての変換単位。")。

とについてf2_1()f2_2()[basic.stc.static] para.2は、「静的ストレージ期間の変数に初期化または副作用のあるデストラクタがある場合、未使用のように見えても削除されない、...」と述べています。これは、副作用が含まれている場合に呼び出されることが保証されていることを意味します。

于 2012-12-04T10:30:38.870 に答える
0

私があなたの質問を正しく理解している場合、C ++は、1つのコンパイルユニット(つまり、cppファイル)内の宣言の順序によって変数の初期化順序を保証します。コンパイル単位間の初期化の順序は定義されていません。

コンパイルの過程で、のf2_*関数が実行されていなくても、標準に従った関数が呼び出されfile2.cppます。しかし、コンパイラが十分に賢い場合、結果のプログラムが標準に準拠しているかのように動作すると判断した場合は、コンパイラを完全に省略することができます。(つまり、これらの関数が呼び出されているプログラムと呼び出されていないプログラムの動作に違いがないことを疑いの余地なく保証できる場合)

于 2012-12-04T10:31:22.197 に答える