Thứ tự của các đánh giá của các nhà khai thác ^=
cũng được xác định. Những gì không được xác định rõ ràng là thứ tự trong đó a
và b
được sửa đổi.
a ^= b ^= a ^= b;
tương đương với
a ^= (b ^= (a ^= b));
Một nhà điều hành không thể được đánh giá trước đối số của nó được đánh giá, vì vậy nó chắc chắn sẽ thực hiện a ^= b
đầu tiên.
Lý do để có hành vi không xác định này là, để cho trình biên dịch linh hoạt hơn trong việc tối ưu hóa, nó được phép sửa đổi các giá trị biến theo bất kỳ thứ tự nào nó chọn.Nó có thể chọn để làm điều này:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a1;
a = a2;
b = b1;
hay này:
int a1 = a^b;
int b1 = b^a1;
a = a1;
int a2 = a^b1;
a = a2;
b = b1;
hoặc ngay cả điều này:
int a1 = a^b;
int b1 = b^a1;
int a2 = a^b1;
a = a2;
a = a1;
b = b1;
Nếu trình biên dịch chỉ có thể chọn một trong ba cách để làm điều gì đó, điều này sẽ chỉ là hành vi "không xác định". Tuy nhiên, tiêu chuẩn đi xa hơn và làm cho hành vi này là "không xác định", về cơ bản cho phép trình biên dịch giả định rằng nó thậm chí không thể xảy ra.
Nguồn
2013-07-04 17:05:24
Nếu bạn viết mã khó mà nói được những gì đang xảy ra, hãy tự hỏi liệu có cách nào đơn giản hơn mà nhà phát triển tương lai có thể hiểu không? –
Lưu ý rằng nếu bạn đã thấy điều này trong mã C++, C++ có các quy tắc khác nhau cho toán tử gán cho phép cấu trúc nhất định (tôi không chắc chắn về cấu trúc này) không xác định trong C. – hvd
có thể trùng lặp của [Sequence Point - Xor Hoán đổi trên Array nhận được kết quả sai] (http://stackoverflow.com/questions/9958514/sequence-point-xor-swap-on-array-get-wrong-result) –