2012-04-10 4 views
3

これらは、いつも私を気にしていると私はへの決定的な答えを見つけていない静的な地元の人々についての二つの質問です:2つのこと

struct Test 
{ 
    static inline const char* name() 
    { 
    static const char* nameValue = "Name of Test"; 
    return nameValue; 
    } 
}; 

このメソッドはインラインであるため、このメソッドを呼び出す各コンパイル単位にこのメソッドのコピーが存在するはずです。しかし、ローカル静的変数nameValueのインスタンスは1つだけでなければなりません(私が間違っていれば私を修正してください)。これはどのように達成されますか?関数の多くのインスタンスが生成されていますが、それらはすべて同じ静的ローカルを参照しています。コンパイラは、各関数に関連付けられた静的ローカルのグローバルテーブルを名前で管理していますか?

質問2:

struct Init 
{ 
    Init() {printf("init created\n");} 
    ~Init() {printf("init destroyed\n");} 
}; 

struct Test 
{ 
    static void func() 
    { 
     static Init init; 
    } 
}; 

静的ローカル初期オブジェクトがFUNCの最初の呼び出し時に、一度だけ構築されます()。 func()の最初の呼び出しはいつコンパイラによって分かりますか?これがこのfuncの最初の呼び出しであるかどうかは、実行時にフラグを維持していますか?

+0

これは、実装が定義しているので、コンパイラがどのようなコンパイラを使用しているかを記述する必要があります。 –

+0

私は、使われている技術が一般的だと思いました。もしそうでなければ、コンパイラがg ++ –

答えて

2

これは本当に2つの無関係な質問です。

最初に、さまざまな解決策があります。おそらく最も頻繁な は弱い記号と呼ばれるものです。大まかに言えば、コンパイラ は、すべてのオブジェクトファイル内の特定の名前のインスタンスを生成します。 はその関数を使用し、リンカは重複をスローアウトし、 のみを最終プログラムに保持します。

2番目の場合、通常の解決策は、ブール変数 をオブジェクトに関連付けて生成し、オブジェクトが スコープに入ったときにこれをテストすることです。

+0

ええと、ホスト機能が実行されるたびにブーリアンフラグをチェックするオーバーヘッドがローカルスタティックにあるとします。 –

+0

@AlexanderVassilev:そうですが、それを考えるのはあまり前もって最適化されています。ちょうど 'static'を頻繁に使用しないでください。もしあなたのプログラムがマルチスレッドであれば、それを避けられないならばその間接費を考える。 –

+0

@AlexanderVassilev動的初期化がある場合のみ。いずれにしても、テストの費用はおそらく無視できるものです。 –

関連する問題