2016-10-20 7 views
4

정적 스토리지 ios_base::Init의 인스턴스를 정의 <iostream> 것처럼한다 번역 유닛 <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 사양을 무시한다고 생각하지 않으며 A.cpp에 <iostream>을 포함 시켰습니다. 사양에 따르면 충분합니다.

+6

정확한 코드를 정확하게 입력하십시오. – bmargulies

+0

완료 (15 문자) – marmistrz

+0

이것은 컴파일되지 않습니다. –

답변

6

단락의 전체 인용은 다음과 같습니다

전에 또는 처음 시간 클래스 ios_base의 객체 시간 동안의 개체를 구성하고 협회가 설립 :: 초기화가 구성되고, 어쨌든 주 본문이 시작하기 전에 실행.

그리고 그들이 그렇게 구현은 객체 이전 요구되는 것보다 초기화하는 것이 좋습니다 수행하는 것이 가능한 경우 각주

293) 293).

그래서 iostreams는 에서 가장 늦게으로 입력 할 수 있습니다. 번역 단위에 <iostream>이 포함되어 있지 않으면 이전에 작업해야한다는 엄격한 요구 사항이 없습니다.

당신은 이것을 피할 수있는 방법을 발견했습니다!

B.cpp에서 foo()을 호출하면 A.cpp에 포함 된 ios_base::Init 인스턴스가 초기화되었거나 초기화되지 않았을 수 있습니다.

+0

'B.cpp'에''을 명시 적으로 포함 시키면 효과가 있습니까? – marmistrz

+2

예. 그렇습니다. 하지만 이상한 해결 방법입니다. –