2012-03-29 16 views
5

Trong cpp, kết quả của đoạn mã sau là: 5 5 5 Nhưng trong java, kết quả của đoạn mã giống nhau là: 3 5 7 Tôi không biết tại sao, có ai có thể giải thích nó không? Cảm ơn rất nhiều!Ưu tiên biểu thức? Kết quả này xảy ra như thế nào?

class H 
{ 
    public: 
    H &pr (int n, char * prompt) 
    { 
     cout<<prompt<<n<<" "; 
     return *this; 
    } 

    H &fn(int n) 
    { 
     return pr(n,""); 
    } 
}; 

void test() 
{ 
    int v=3; 
    H h; 
    h.fn(v).fn(v=5).fn((v=7)); 
} 
+2

Câu trả lời ngắn gọn là "C++ không phải là Java". –

+0

BTW, tôi yêu các câu hỏi cho phép tôi phá vỡ một số tháo gỡ. :) –

Trả lời

6

Trong cpp, kết quả của đoạn mã sau là: 5 5 5 Nhưng trong java, kết quả của đoạn mã giống như sau: 3 5 7 Tôi không biết tại sao,

Vì C++ không phải là Java :)

Bạn đang biến đổi biến số v trong hai lần gọi hàm cuối cùng. Chúng ta hãy nhìn vào dissassembly (debug vào đây để xem mọi thứ rõ ràng hơn, trong phiên bản một giá trị tĩnh của 5 được sử dụng, nhưng nó cũng có thể là 7 cũng giống như dễ dàng Bạn sẽ thấy lý do tại sao.):

h.fn(v).fn(v=5).fn((v=7)); 
00411565 mov   dword ptr [v],7 
0041156C mov   dword ptr [v],5 
00411573 mov   eax,dword ptr [v] 
00411576 push  eax 

Trình tự đánh giá biểu thức không được bảo đảm là thứ tự mà bạn gọi các hàm ở đây. Bạn đang sửa đổi v giữa sequence points. 7 được gán cho v, sau đó 5, sau đó chức năng đầu tiên được gọi. Lưu ý rằng nó không phải là 7 và sau đó 5 theo thứ tự đó, nó có thể được đổi chỗ! Thứ tự đánh giá là không xác định, nó có thể là bất cứ điều gì.

Bạn có một chuỗi các chức năng làm biến đổi v hai lần. Bạn không thể dựa vào thực tế là mỗi đột biến sẽ xảy ra theo thứ tự bạn đã gõ ở đây.

Chúng tôi có thể đơn giản hóa nó. Giả sử chúng ta có hai hàm; xy cả hai đều trả lại int. Nếu tôi viết:

int k = x() + y(); 

Không có gì bảo đảm rằng x() sẽ được gọi trước khi y(). Vì vậy, nếu bạn đang thay đổi một đối số chung cho cả hai hàm thì đột biến có thể xảy ra trong cuộc gọi đến số y() trước tiên, đó là những gì bạn đang thấy.

+1

+1 Để làm cho nó rõ ràng hơn một chút: Chương trình có * Hành vi không xác định * theo tiêu chuẩn, và điều đó có nghĩa là chương trình về cơ bản có thể tạo ra bất kỳ đầu ra nào sau đây: 3 5 6; 3 5 5; 3 7 7; 5 5 5; 5 5 7; 5 7 7; 7 7 7 (và có thể những người khác mà tôi bỏ qua ở giữa) –

+0

Tôi đã có nó, cảm ơn rất nhiều. – newda

2

Vấn đề ở đây là tiêu chuẩn không đảm bảo cách biểu thức được đánh giá.

Oh tốt, nó có phải nó một phần nhưng nếu bạn biên dịch mã mà bạn nhận được một cảnh báo cụ thể mà nói

warning: operation on ‘v’ may be undefined 

Tôi nghĩ rằng câu hỏi này có thể soi sáng cho bạn về vấn đề này: Is this code well-defined?

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