19

例:

struct Foo { Foo() { printf("foo\n"); } };
static Foo foo;

__attribute__((constructor)) static void _bar() { printf("bar\n"); }

それは決定論的な天気ですかfoo、それともbar最初に印刷されますか?

(静的オブジェクトのコンストラクターが常に最初に実行されることを願っていますが、確信が持てず、コンストラクター属性に関するGCCのドキュメントはそれについて何も述べていません。)

4

2 に答える 2

15

fooオブジェクトは宣言の順序で初期化されるため、最初に出力されます。実行して見てください:

ちなみに、__attribute__((constructor))標準 C++ ではありません。GCC の拡張機能です。したがって、プログラムの動作は、GCC がどのように定義したかによって異なります。fooつまり、最初に印刷されるため、実装定義です。

ドクター曰く、

コンストラクター属性により、実行が main () に入る前に関数が自動的に呼び出されます。同様に、 destructor 属性により、 main () が完了した後、または exit () が呼び出された後に関数が自動的に呼び出されます。これらの属性を持つ関数は、プログラムの実行中に暗黙的に使用されるデータを初期化するのに役立ちます。

オプションの整数の優先順位を指定して、コンストラクター関数とデストラクター関数が実行される順序を制御できます。優先度の数値が小さいコンストラクターは、優先度の数値が大きいコンストラクターよりも前に実行されます。逆の関係がデストラクタに当てはまります。そのため、リソースを割り当てるコンストラクタと同じリソースの割り当てを解除するデストラクタがある場合、通常、両方の関数の優先度は同じです。コンストラクター関数とデストラクター関数の優先順位は、名前空間スコープの C++ オブジェクトに指定されているものと同じです(C++ 属性を参照)。

太字のテキストは、前に述べたように、オブジェクトが宣言の順序で初期化されることを意味していると思います。これは、オンライン デモでもほぼ確認されています。

あなたもこれを読みたいと思うでしょう:

初期化順序を制御/変更したい場合は、init_priority属性を使用して優先順位を指定できます。ページから取得:

Some_Class  A  __attribute__ ((init_priority (2000)));
Some_Class  B  __attribute__ ((init_priority (543)));

ここで、Bは の前に初期化されAます。

于 2011-12-08T15:39:47.917 に答える