2015-01-14 11 views
5

Tôi có một chương trình thử nghiệm rất đơn giản sử dụng istringstreams để đọc trong các số nguyên từ chuỗi std ::. Mã này là:C++ Dòng đầu vào: thứ tự hoạt động trong Solaris so với 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; 
} 

Khi tôi chạy trên Solaris 10, nó tạo ra kết quả như sau:

1 2 
3 4 
5 6 
7 8 

1 2 
3 4 
5 6 
7 8 

Tuy nhiên, khi tôi chạy nó dưới CentOS 7, tôi nhận được:

1 0 
3 0 
5 0 
7 0 

1 4 
3 6 
5 8 
7 0 
4204240 2 

Có ai biết tại sao nó sẽ khác với Linux chứ không phải dưới Solaris? Nó rõ ràng là đọc trong giá trị vào bản đồ trước khi đọc vào chỉ mục cho bản đồ, nhưng tôi không biết tại sao. Tôi có thể làm cho nó hoạt động dưới Linux bằng cách thay đổi mã hơi:

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; 
} 

Tôi biết đó là một sửa chữa hợp lệ, nhưng tôi có những người xung quanh tôi muốn biết tại sao nó lại khác. Chúng tôi đang di chuyển từ Solaris sang Linux và khi những thứ như thế này xuất hiện, họ muốn biết tại sao. Tôi không biết tại sao tôi yêu cầu hướng dẫn.

+0

Thực tế là nó hoạt động trên một máy và không có nghĩa là nó là hành vi chưa được xác định – smac89

+3

Giống như các thứ tự hoạt động tương tự gotchas được đăng ở đây, biểu thức 'is >> idx >> imap [idx]' đánh giá biến nhiều lần trong khi sửa đổi nó ít nhất một lần. Xem http://stackoverflow.com/questions/4176328 –

Trả lời

5
is >> idx >> imap[idx] 

biểu hiện này tương đương với

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

Các đánh giá của đối số cho các chức năng tương tự là unsequenced tương đối với nhau; hoặc operator>>(is, idx) hoặc imap.operator[](idx) có thể được đánh giá trước tiên (tức là is >> idx hoặc imap[idx] có thể được đánh giá trước). Nếu giá trị thứ hai được đánh giá trước, thì kết quả là một giá trị liên quan đến giá trị tương ứng với giá trị của idx trên bản đồ; đó là giá trị này sẽ được ghi đè bởi lần đọc thứ hai và không phải giá trị tương ứng với giá trị mới của idx.

Mã sửa đổi sửa lỗi này bằng cách đảm bảo rằng idx được đọc trước khi truy cập imap[idx].

Các vấn đề liên quan