2014-09-23 4 views
4

아무데도 문제가 발생했습니다.변수의 정적 초기화가 실패합니다.

갑자기 내 프로젝트에서 일하는 것이 중단되었습니다. Xcode 5.1.1 (LLVM 3.4, clang 5.1)을 사용하고 있습니다. 문제는 대부분의 정적 변수가 시작시 더 이상 초기화되지 않는다는 것입니다.

나는이 문제로 이어질 수있는 어떤 변화도 없었지만 무엇이 그것을 일으킬 수 있었는지, 그리고 어떻게 해결할 수 있는지 궁금해. 크기가 단지 쓰레기 값 실현하기 위해, 벡터 요소를 추가하려고 할 때 나는 길이 예외가 프로그램을 실행하여

// File.h 
class MyClass { 
    static std::vector<MyObject*> data; 
} 

// File.cpp 
std::vector<MyObject*> MyClass::data; 

:

내가 좋아하는 간단한 상황에 대해 이야기하고있다. 이것은 명백한 이유없이 다른 파일의 다른 정적 필드에서 발생했습니다. 코드 자체는 라이브러리로 사용되지 않고 그대로 컴파일되며 지금까지 완벽하게 작동했습니다.

편집 : 출시 계획을 세우는 데 문제가 나타나지 않고 예측할 수 없게됩니다.

편집 : 예상했던 것보다 더 이상합니다. 수동으로 초기화 한 다른 정적 변수도 작동하지 않습니다. 나는 init() 후라고 i의 값을보고 getInstance() 처음 사용할 때 내가 두 개의 서로 다른 주소를 얻는 경우에 지금

// .h 
class MyClass { 
    static MyClass* i; 
public: 
    static void init(); 
    static MyClass* getInstance(); 
} 

// .cpp 
MyClass* MyClass::i; 

void MyClass::init() { i = new MyClass(); } 
MyClass* getInstance() { return i; } 

:

(lldb) p MyClass::i 
(MyClass *) $0 = 0x09e36a50 

(lldb) p MyClass::i 
(MyClass *) $1 = 0x00620000 

와 잘못된 코드는 다음과 같다 나는()이 단지 한 번 (그리고 전에 (getInstance()`) 호출되기 때문에 이것이 가능하지 않다.

+0

다른 정적 객체를 생성하는 동안 사용됩니까? – hvd

+0

@hvd : 아니요, 실제로 프로그램이 이미 시작되면 힙 객체를 할당 할 때 실제로 예외가 발생합니다 (자체는'std :: vector '에 추가됩니다). 그러나 이것은 내가 발견 한 다른 경우에도 마찬가지입니다. – Jack

+6

이와 같은 비 trival 정적 변수는 너무 많은 두통을 유발하여 사용을 중단했습니다. 반환 된 함수의 정적 로컬은 더 안전합니다. –

답변

1

다른 번역 단위로 정적 범위 객체를 선언 할 때, 시공 순서가 정해지지 않았다.

예를 들어 다른 일부 정적 단위 개체의 생성자 일부로 실행되는 코드에서 MyClass :: Data를 사용하려고하는 경우 일부 번역 단위에서 MyClass의 여부를 지정하지 않습니다. : 데이터는 다른 정적 범위 객체의 생성자 앞이나 뒤에 생성됩니다. MyClass :: Data에 액세스하는 코드가 호출되고 MyClass :: Data가 아직 생성되지 않은 경우 이는 분명히 정의되지 않은 동작입니다.

일반적인 C++ 구현에서 링커가 최종 실행 파일을 함께 처리하는 순서에 따라 순서가 달라집니다. 전체 응용 프로그램을 다양하게 변경하면 링커가 서로 다른 객체 모듈을 서로 다른 순서로 묶어서 정적으로 범위가 지정된 객체의 상대적 구성 순서를 변경하는 것이 가능할 수 있습니다.

많은 구현은 정적 범위의 객체의 생성/초기화 순서를 제어하기위한 구현 고유의 메커니즘을 제공합니다. 예를 들어, gcc는 init_priority 속성을 사용하여이를 제어 할 수 있습니다. https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

+0

+1 ....하지만 이것을 완전히 피하는 것이 좋습니다. 대신 function -static's를 사용하십시오. –

관련 문제