2012-05-21 11 views
5

これは可能ですか?関数を呼び出すことで静的変数を初期化することが可能です

static bool initialize() 
{ 
    TRC_SCOPE_INIT(...); 
    ... 
} 

static bool initialized = initialize(); 

非常に長い話を短くするために、私は、スレッドXが開始される前に(可能な限り早期に(デバッグメッセージを初期化するために)一連のマクロを呼び出す必要がある、と私は知っている能力を持っていませんスレッドXが開始されたとき)。

+1

'main()'ルーチンで 'pthread_once(3)'の呼び出しを挿入できますか? – sarnold

+0

@KingsIndian: 'bool'はC99で' stdbool.h'ヘッダで有効です。 – icktoofay

+0

@icktoofayとにかくc99として指定されていないので、C++タグが追加されました。 –

答えて

6

質問を最初に見たとき、CとC++の両方にタグが付けられました。 boolはC++と同じように(ほとんどC言語でboolという名前を得るには<stdbool.h>ヘッダーが必要です)、boolはC99およびC11の型です。コードはCまたはC++である可能性があります。

二つのタグのための答えがある:C++で

  • 、はい。

  • Cでは、

これらは同じ言語ではありません。デモンストレーションが必要な場合は、これと同じように良い例です。

+2

質問には、最初に投稿されたときにのみ「c」というタグが付けられました。 @ KingsIndianは 'bool'のために' C++ 'タグを追加しましたが、' bool'はC99で有効で、元の投稿からは何とかC++に関連しているという兆候はなかったので、編集を元に戻しました。 – icktoofay

+0

@icktoofay:明確化のおかげで;私は変更を認識するために私の答えを少し調整しました。 –

+0

(a)C++ 11でconstexprを使うことができます。(b)驚くほどコンパイラのサポートがあります。 –

1

初期化する「stuff」は、初期化する関数への呼び出しと同じ翻訳単位で定義されている場合は、これは問題ありません。また、コールサイトの上に定義する必要があります。そうしないと、初期化されていない値を使用するため、未定義の動作が発生する可能性があります。

これを回避する方法の1つは、代わりにポインタを使用することです。静的に初期化されたポインタは、実行可能イメージにコンパイルされるため、他の翻訳単位で定義された静的変数によって使用される場合、未定義の動作のリスクはありません。静的初期化関数では、 "stuff"を動的に割り当て、ポインターをポイントして後でアクセスできるようにします。

4

あなたはGCC(あるいは打ち鳴らす)を使用している場合は、__attribute__((constructor))を使用することができます(。あなたは私はあなたがあなたの処分でPOSIXスレッド機能を持っていると仮定するつもりです、スレッドを述べたので)

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; 
} 
1

この正確な目的のためにpthread_once関数が存在します。必要に応じてinit_oncepthread_once_t init_onceとして、静的記憶域期間と定義され、そしておそらく外部リンケージとさ

pthread_once(&init_once, initialize); 

:どこでもあなたはinitializeはすでに書き、呼び出されていることを確認する必要があります。