2013-01-08 57 views
1

我正在使用g ++ 4.3和Rogue Wave庫在Linux系統上編寫一個簡單的測試程序。我在這裏面臨的問題是可以編譯下面的代碼,但是當我運行它時,會在這一行上彈出分段錯誤: _aClasses.insertKeyAndValue(100,1000);在Linux上使用RWTValHashMap和g ++的奇怪問題

當我使用aCC編譯器在HPUX機器上運行相同的代碼時。它運行順暢,這讓我感到困惑。那是因爲g ++初始化靜態變量的方式與aCC不同嗎?任何人都知道這裏發生了什麼?提前致謝。

A.hxx

#include <rw/tvhdict.h> 
#include <rw/cstring.h> 
#include <rw/rwdate.h> 
#include <rw/rstream.h> 

using namespace std; 

class A 
{ 
    public : 
    A(); 
    static void add(); 
    struct long_hash { 
     unsigned long operator() (const long& x) const { return x;}; 
    }; 
    struct long_equal { 
     RWBoolean operator() (const long& x, const long& y) const { return x==y;}; 
    }; 
    private: 
    static RWTValHashMap<long, long, long_hash, long_equal> _aClasses; 
}; 

A.cxx

#include "A.hxx" 

RWTValHashMap<long, long, A::long_hash, A::long_equal> A::_aClasses; 

A::A() 
{ 
    cout<<"init A"<<endl; 
} 

void A::add() 
{ 
    _aClasses.insertKeyAndValue(100,1000); 
} 

B.hxx

class B 
{ 
    public: 
     B(); 
}; 

B.cxx

#include "B.hxx" 
#include "A.hxx" 

B::B() 
{ 
    A::add(); 
} 

Main.cxx

#include "A.hxx" 
#include "B.hxx" 

static B c; 

int main() { 
    cout<<"main"<<endl; 
    return 0; 
} 

回答

1

從不同的翻譯單元的靜態成員的初始化的順序(本質的不同CPP/CXX文件)是not specified。因此,對於不同的編譯器,static B cRWTValHashMap<long, long, A::long_hash, A::long_equal> A::_aClasses是否會首先被初始化,並且甚至在使用相同的編譯器時可能會改變。你以前的編譯器總是按照期望的順序初始化它們,這很簡單。

避免這種情況的方法是使用'construct on first use idiom'

+0

我看了之前的文章,並實現了基於該理論的東西,但它並沒有我的情況下工作。 – user1349058

+0

@ user1349058我建議你發佈一個關於你遇到的問題的問題,因爲你不能真正修復靜態初始化順序,只能解決它。 –

+0

我通過使用__attribute__((init_priority()))對其進行了修復,強制一個var首先被初始化。而且,鏈接順序也很重要。 – user1349058