これは可能ですか?
static bool initialize()
{
TRC_SCOPE_INIT(...);
...
}
static bool initialized = initialize();
非常に長い話を短くするために、(デバッグ メッセージを初期化するために) 一連のマクロをできるだけ早く (スレッド X が開始される前に) 呼び出す必要があり、スレッド X がいつ開始されるかを知る能力がありません。
これは可能ですか?
static bool initialize()
{
TRC_SCOPE_INIT(...);
...
}
static bool initialized = initialize();
非常に長い話を短くするために、(デバッグ メッセージを初期化するために) 一連のマクロをできるだけ早く (スレッド X が開始される前に) 呼び出す必要があり、スレッド X がいつ開始されるかを知る能力がありません。
最初に質問を見たとき、C と C++ の両方のタグが付けられていました。は C99 と C11 の型であるため、コードは C または C++ である可能性があります。これは、C++ の場合と同じです (ほとんど; C では、名前を取得するためにヘッダーbool
が必要です)。<stdbool.h>
bool
2 つのタグの答えは次のとおりです。
C++ では、はい。
Cでは、いいえ。
それらは同じ言語ではありません。デモンストレーションが必要な場合は、これが最も良い例です。
GCC (または clang) を使用している場合は、次を使用できます__attribute__((constructor))
。
static bool initialized = false;
__attribute__((constructor))
static void initialize(void) {
initialized = true;
// do some other initialization
}
int main(int argc, char **argv) {
// initialize will have been run before main started
return 0;
}
(スレッドについて言及したので、POSIXスレッド機能を自由に使用できると仮定します。)
関数はまさにこのpthread_once
目的のために存在します。initialize
すでに呼び出されていることを確認する必要がある場所には、次のように記述します。
pthread_once(&init_once, initialize);
whereinit_once
は静的ストレージ期間で定義され、場合によっては必要に応じて外部リンケージを使用して定義されpthread_once_t init_once
ます。
初期化する「もの」が、それを初期化する関数の呼び出しと同じ翻訳単位で定義されている場合、これは問題ありません。さらに、呼び出しサイトの上で定義する必要があります。そうしないと、初期化されていない値の使用により、未定義の動作が発生する危険があります。
これを回避する 1 つの方法は、代わりにポインターを使用することです。静的に初期化されたポインターは実行可能イメージにコンパイルされるため、他の翻訳単位で定義された statics によって使用された場合、未定義の動作が発生するリスクはありません。静的初期化関数では、「もの」を動的に割り当て、ポインターをそれを指すように設定して、後でアクセスできるようにします。