2017-03-23 2 views
0

RHEL 6.7에서 RHEL 7.3으로, 그리고 gcc 4.4.7에서 gcc 4.8.5로 이동하려고합니다.정적 변수가 초기화되지 않습니다.

정적 변수 (클래스 정의 외부에서 초기화 됨)가 초기화되지 않습니다. 예를 들어, 파일 unitprot_selfsintent.cc에 :

util_Registry<unitprot_SelfsIntent> * unitprot_SelfsIntent::d_selfsIntents = 
    new util_Registry<unitprot_SelfsIntent>(); 

d_selfsIntents는 unitprot_selfsintent.h 정적 선언된다.

util_Registry는 템플릿 클래스입니다. 우리가이 레지스트리에 뭔가를 배치하려고 시도 할 때 응용 프로그램 코어가 덤프합니다. d_selfsIntents는 0 포인터이며 초기화되지 않았습니다.

나는 우리가 레지스트리에 어떤 것을 넣으려고 시도하기 오래 전에 완성되었을 것이라고 생각했을 것이다.

모든 것이 이전 구성에서와 같이 작동합니다. 새 구성에서이 문제가 발생하기 위해 변경된 사항은 무엇입니까? 호출해야하는 새 컴파일러 옵션이 있습니까?

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const char * si) 
{ 
    OTC_String selfsIntent(si); 
    return registerObject(selfsIntent); 
} 

:

static unitprot_Selfintent * f_en_route_to_escort = 
    unitprot_SelfsIntent::registerObject("en_route_to_escort"); 

unitprot_SelfsIntent :: registerObject는 다음과 같습니다 : 다음과 같이

자세한 내용은 ...

또 다른 클래스, unit_groundresunitc2.cc는 정의 된 정적 변수를 가지고 registerObject를 OTC_String으로 호출하면 다음과 같습니다.

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const OTC_String & si) 
{ 
    unitprot_SelfsIntent * regObj = d_selfsIntents->find(si); 

    if (regObj == 0) 
    { 
     regObj = new unitprot_SelfsIntent(si); 
     d_selfsIntents->registerObject(regObj); 
    } 

    return regObj; 
} 

d_selfsIntents가 util_Registry 인 d_selfsIntents에서 find (const OTC_String & name)를 호출하면 d_selfsIntents가 초기화되지 않았기 때문에 코어 덤프가 발생합니다.

그렇다면 Matteo의 질문에 대답하기 위해 다른 정적 구조 (f_en_route_to_escort)를 초기화하여 정적 구조 (d_selfsIntents)에 액세스하려고합니다.

다른 하나를 초기화하기 전에 하나를 사용하여 문제가 발생합니다. 제가 가지고있는 질문은 왜 이것이 지금 문제가 되는가하는 것입니다. 그의 제안은 오래전에 다루어 져야 할 것으로 보입니다. 우리의 코드에는 이와 같은 예제가 수백 개가 있으며 15 년 넘게 개발되어 지금까지 결코 문제가되지 않았습니다.

주문, 컴파일러 또는 링커는 무엇을 설정합니까? 여기서 두 개의 컴파일 단위는 unitprot (unitprot_SelfsIntent의 경우) 및 util (util_Registry의 경우)입니다. 우리는 특정 순서로 컴파일하지만, 링크 타임이나 런타임에 문제가 발생한다고 생각합니다.

는 다른 정적 데이터 멤버 '초기화 중 또는 실행이 이미 주요 입력 한 후 이러한 정적 데이터 멤버를 액세스하려고 여부를 내가 질문에서 그리워
sglasgow

+0

구글 * 정적 초기화 순서 대 실패 *. 당신은 처음에는 운이 좋았지 만 지금 운이 다되었습니다. 그런 삶입니다. –

답변

1

뭔가가, 감사합니다.

첫 번째 경우 변수의 정적 초기화가 다른 컴파일 단위에 정의 된 순서와 관계없이 특정 순서대로 수행되지 않을 수 있습니다.

개선 할 트릭이있을 수 있지만이를 처리하는 일반적인 방법은 해당 멤버에 대해 공용 getter 역할을하는 정적 메서드 내부에서 초기화를 수행하는 것입니다. 단순화되면, 이는 싱글 톤 패턴을 사용하는 것과 같습니다.

귀하의 예는 다음 헤더에 다음과 같을 것이다 :

class unitprot_SelfsIntent : ... 
{ 
public: 
    static util_Registry<unitprot_SelfsIntent>* GetSelfsIntents(); 
//... 
private: 
    static util_Registry<unitprot_SelfsIntent>* d_selfsIntents; 
//... 
}; 

과 같은 구현 뭔가 :

util_Registry<unitprot_SelfsIntent>* unitprot_SelfsIntent::GetSelfsIntents() 
{ 
    // usually multithreading would be handled here 

    d_selfsIntents = new util_Registry<unitprot_SelfsIntent>(); 

    // some more synchronization 

    return d_selfsIntents; 
} 
관련 문제