2017-04-18 1 views
2

次のコードは特定のコンパイラでコンパイルされていません。C++スコープの解像度と条件を持つ3進演算子

#include <iostream> 

using namespace std; 

class A{ 
     public: 
       static const int x = 12; 
       static const int y = 16; 
}; 

int main(){ 
     int a = 12, b = 19; 
     int z = (a==b)?(A::x):(A::y); 
     cout<<z<<endl; 
     return 0; 
} 

コンパイラG ++(GCC)4.8.5 20150623(Red Hatの4.8.5-11)は正常にコンパイル。

コンパイラG ++(GCC)4.4.7私は、その後、trueまたはfalseによってラインint z = (a==b)?(A::x):(A::y);状態(a==b)を交換する場合は20120313(Red Hatは4.4.7-17)は、コンパイルエラー

test.cpp:(.text+0x20): undefined reference to `A::x' 
test.cpp:(.text+0x28): undefined reference to `A::y' 

を引き起こしていること正常にコンパイルされます。

指定されたコンパイラで修正する理由とその理由は何ですか?

+1

修正されたコンパイラのバグを見つけたようです。 – dasblinkenlight

+0

後者のコンパイラはおそらくすべてを 'z = 16'に最適化することができます。生成されたマシンコードを見てみましょう。 –

+0

C++でコンパイルしたDd 0x/11がオンになっていますか? [ここ](https://godbolt.org/g/2eyWlM)を再現できません – NathanOliver

答えて

0

gcc 4.4の弱い/バグのあるC++ 0xシンボルリンケージのように見えます。 gcc 4.4はシンボルがあるが、コンパイル単位の1つでシンボルを「実装」するのを忘れていることをリンカに伝えているようです。

静的メンバーA :: xとA :: yの初期化を明示的に1つのユニークなコンパイル単位(例:対応する.cppファイル)に入れたら、あなたのコードは両方のコンパイラと互換性があります。