2016-10-20 8 views
4

:静的ストレージとios_base::Initのインスタンスを定義<iostream>かのようでなければならない翻訳単位で<iostream>などの静的順初期化失態、入出力ストリームとC++ 11

結果期間。同様に、プログラム全体は、静的記憶域期間を持つios_base::Initの少なくとも つのインスタンスがあったかのように動作するもの。これは意味

その私のコードは、そのように見える場合:

// A.cpp 
#include <iostream> 
using namespace std; 
unsigned long foo() { 
    cerr << "bar"; 
    return 42; 
} 

// B.cpp 

using namespace std; 
extern unsigned long foo(); 

namespace { 
unsigned long test() { 
    int id = foo(); 
    return id; 
} 

unsigned long id = test(); 
} 


int main() { 
    return 0; 
} 

私は、cerrを呼び出すのは安全です。静的な初期化の失敗の危険はありません。

残念ながら、そのコードsegfaults ...なぜですか?私はgcc 6.2.1がC++ 11仕様を無視することを決めたとは思わないし、<iostream>をA.cppに含めた。仕様書によるとそれで十分です。

+6

厳密には正確なコードを入力してください。 – bmargulies

+0

完了(15文字) – marmistrz

+0

これはコンパイルされません。 –

答えて

6

段落の完全な引用が含まれています:

前、または最初 時間クラスios_baseのオブジェクトの間にいくつかの時点でオブジェクトが構築され、アソシエーションが確立されている:: Initが構成されており、いずれにしても、メイン本体が起動する前に が実行されます。 293)

そして脚注

293との)彼らがそうすることが可能である場合には、実装が早く必要以上のオブジェクトを初期化することをお勧めします。

したがって、iostreamsは、メインに入るときにで最新ので動作することが保証されています。翻訳単位に<iostream>が含まれていない限り、早期に作業する必要があります。

あなたはこれを回避する方法を見つけました。

B.cppからfoo()を呼び出すと、A.cppに含まれるios_base::Initインスタンスが初期化されている場合とされていない場合があります。

+0

'B.cpp'に' 'を明示的に含めるとうまくいきましたか? – marmistrz

+2

はい、そうすべきです。しかし、それは奇妙な回避策です。 –

関連する問題