2014-12-27 6 views
4

Google 팀에서 오랫동안 사용해온 큰 코드가 있습니다. 그러나 그것이 내 컴퓨터에서 컴파일 될 때 문제가 있다는 몇 주. 이 코드는 인텔 아톰 CPU 용으로 크로스 컴파일되어 특정 컴퓨터에서 실행됩니다.clang으로 컴파일하는 특정 컴퓨터에서 (null)이 실행되는 경우 ++

다른 컴퓨터와 달리 내 컴퓨터에서 컴파일 될 때 segmentation fault이 발생합니다. 분할 결함 실행 안되는 if 블록 내부이다

내 시험
. 
. 
. 

private: 
    static __thread Settings* theSettings; 

public: 
    static Settings& getSettings() {return *theSettings;} 

. 
. 
. 

__thread Settings* Global::theSettings = 0; 

열고 설정 :: 글로벌 값이 변경되지 않고 동일 다음과 같이

Settings *s = &Global::getSettings(); 
std::cout << "Pointer value before if : " << s << std::endl; 
if(s != 0) 
{ 
    std::cout << "Pointer value after if : " << &Global::getSettings() << std::endl; 
    . 
    . 
    . 
} 

Global::getSettings()은 0으로. 위 코드의 출력은 이것이다 :

Pointer value before if : 0 
Pointer value after if : 0 

질문 : 어떻게 if가 제로인 상태로 실행할 수 있습니다!

P .: 데비안 컴퓨터에서 코드를 컴파일하기 위해 clang ++을 사용하고 있습니다.

+2

제 생각에 컴파일러는'Global :: getSettings()'에서 참조를 보지 못했습니다.'Global :: theSettings'는 null이 될 수 없습니다 (또는's'가'& something ' '그것이 null 일 수 없다고 추측 함), null 체크를 최적화했다. –

+0

이것은 인상적인 것입니까? 아니면 코드가 멀티 스레드입니까? – Christophe

+0

이것은 다중 스레드 코드이지만 정적 변수는 스레드 와이드로 정의됩니다. – Sheric

답변

9

null 포인터를 참조에 저장하는 것은 정의되지 않은 동작입니다.

그래서 일단 참조가되면 컴파일러는 주소가 null이 아닌 것으로 간주하고 Null Check을 최적화합니다.

다른 컴파일러의 "성공"은 정의되지 않은 동작의 한 가지 가능한 증상 일뿐입니다.

비 개체에 대한 참조를 저장하거나 만들지 마십시오.