2015-01-14 6 views
5

私は、std :: stringから整数で読み込むためにistringstreamsを使用する非常に単純なテストプログラムを持っています。コードは次のとおりです。C++入力ストリーム:SolarisとLinuxの操作順序

std::map<int, int> imap; 
int idx, value; 
std::string str("1 2 3 4 5 6 7 8"); 
istringstream is(str); 
while(is >> idx >> imap[idx]){ 
    cout << idx << " " << imap[idx] << endl; 
} 
cout << endl; 

std::map<int, int>::iterator itr; 
for(itr = imap.begin(); itr != imap.end(); itr++){ 
    cout << itr->first << " " << itr->second << endl; 
} 

私は、Solaris 10上でこれを実行すると、それは次の出力を生成します。

1 2 
3 4 
5 6 
7 8 

1 2 
3 4 
5 6 
7 8 

しかし、私はCentOSの7の下でそれを実行したときに、私が取得:

1 0 
3 0 
5 0 
7 0 

1 4 
3 6 
5 8 
7 0 
4204240 2 

Linuxの場合とSolarisの場合とで異なる理由を知っている人はいますか?地図のインデックスを読み込む前に、値を地図に読み込んでいるのは明らかですが、理由はわかりません。私はそれが少しのコードを変更することにより、Linuxで動作させることができます。

std::map<int, int> imap; 
int idx, value; 
std::string str("1 2 3 4 5 6 7 8"); 
istringstream is(str); 
while(is >> idx >> value){ 
    imap[idx] = value; 
    cout << idx << " " << imap[idx] << endl; 
} 

std::map<int, int>::iterator itr; 
for(itr = imap.begin(); itr != imap.end(); itr++){ 
    cout << itr->first << " " << itr->second << endl; 
} 

は、私はそれが有効な修正だけど、私はそれが異なっている理由を知りたい私の周りの人々を持っています。私たちはSolarisからLinuxに移行しています。このようなことが起こったときに、理由を知りたいと思っています。なぜ私は指導を求めているのかわかりません。

+0

これは、あるマシン上で動作し、他のマシンでは動作しないということは、未定義の動作であることを意味します。 – smac89

+3

ここに掲載されている同様の動作オーダーのgotchasと同様に、 'is >> >> idx >> imap [idx]'は、それを少なくとも1回は修正しながら。 http://stackoverflow.com/questions/4176328を参照してください。 –

答えて

5
is >> idx >> imap[idx] 

この式は、同じ関数の引数の評価は互いにunsequenced相対的

operator>>(operator>>(is, idx), imap.operator[](idx)) 

と等価です。最初にis >> idxまたはimap[idx]のいずれかを評価することができます。後者が最初に評価された場合、結果はの古い値に対応する値を参照する左辺値であり、idxです。この値は、新しいの値に対応する値ではなく、2番目の読み取りによって上書きされます。idxです。

imap[idx]にアクセスする前にidxが読み取られるように修正されたコードでこれが修正されています。

関連する問題