2009-11-07 64 views
9

Tôi đã đọc về 'tác dụng phụ' từ this website:tại sao "f = f ++" không an toàn trong c?

nhưng vẫn không hiểu tại sao f = f++ được coi là không an toàn?

Ai đó có thể giải thích?

+0

Duplicate (mặc dù không thực sự rõ ràng nếu bạn không biết câu trả lời tại sao) http://stackoverflow.com/questions/1678519/difference-between-i-and-i –

+1

Ngoài ra còn có một câu hỏi ở đâu đó về lý do tại sao "++ i ++" là bất hợp pháp nhưng không thể tìm kiếm nó! –

+3

Câu hỏi này giải thích rõ ràng tại sao cấu trúc này không an toàn.Câu hỏi mà bạn tham chiếu có mã không hợp lệ _because_ cấu trúc này không an toàn. Hai câu hỏi hoàn toàn hợp lệ khác nhau. – joshperry

Trả lời

16

Sự cố là Sequence Points. Có hai hoạt động trong statment này không có điểm thứ tự, vì vậy không có thứ tự xác định nào cho câu lệnh, là việc chuyển nhượng xảy ra trước hay là gia tăng?

Không có gì nói đó là không an toàn, nó chỉ là không xác định, có nghĩa là triển khai khác nhau có thể có kết quả khác nhau hoặc nó có thể định dạng ổ đĩa cứng của bạn ...

+2

Tôi nghĩ rằng hầu hết mọi người sẽ xem xét định dạng một ổ đĩa một hệ quả không an toàn của 'f = f ++ '. Mặc dù tôi nghĩ hầu hết mọi người đều nói 'không an toàn' không có nghĩa là nó có thể phá hủy thứ gì đó, nhưng bạn không thể phụ thuộc vào những gì nó sẽ làm. –

+0

Tiêu chuẩn C và C++ khá rõ ràng sử dụng thuật ngữ "Hành vi không xác định" trong suốt, và cụ thể trong phần chi tiết thứ tự thực thi trình tự. Tôi đã chỉ sử dụng hyperbole để làm nổi bật sự khác biệt giữa không an toàn và không xác định. – joshperry

+4

hành vi bất hợp pháp ngụ ý mã không an toàn – hasen

4

Sử dụng xx++ (hoặc ++x) trong báo cáo kết quả tương tự cũng hành vi không xác định trong C. Trình biên dịch là miễn phí để làm bất cứ điều gì nó muốn: hoặc tăng x trước khi thực hiện nhiệm vụ, hoặc sau đó. Lấy mã của Ólafur, nó có thể mang lại f == 5 hoặc f == 6, tùy thuộc vào trình biên dịch của bạn.

4

Bài viết tại (cleaned up) link bạn cung cấp cho câu trả lời. "C hầu như không hứa hẹn rằng tác dụng phụ sẽ xảy ra theo thứ tự có thể dự đoán được trong một biểu thức duy nhất." Điều này có nghĩa là bạn không biết thứ tự = và ++ sẽ xảy ra. Nó phụ thuộc vào trình biên dịch.

Nếu bạn theo liên kết từ bài viết đó đến bài viết về sequence points trên cùng một trang web, bạn sẽ thấy trình biên dịch có thể tối ưu hóa giá trị và thời gian ghi lại từ sổ đăng ký vào các biến.

+0

Một chút làm rõ thêm - nó không chỉ phụ thuộc vào trình biên dịch. Những gì trình biên dịch có thể làm có thể không có ý nghĩa gì cả - ngay cả đến điểm mà 2 trường hợp của cùng một câu lệnh (với cùng giá trị bắt đầu cho 'f') có thể tạo ra các kết quả hoàn toàn khác nhau. –

0

Tôi ủng hộ câu trả lời của Arthur về mặt này. Mặc dù việc thực thi toán tử gia tăng bài viết tức là f ++ là khó hiểu, nó không được coi là không an toàn. U đầu tiên nên hiểu cách trình biên dịch diễn dịch nó. cho dù nó sẽ tăng f sau khi nó gặp một kết thúc câu (;) hoặc ngay lập tức sau khi sử dụng giá trị của f.

+1

Đó là * không xác định *, theo nghĩa của tiêu chuẩn C. Điều này không phải là một trường hợp của "bạn phải biết những gì trình biên dịch không". Trình biên dịch có thể làm bất cứ điều gì, bao gồm việc đưa ra một giá trị cho f không tương ứng với bất kỳ thứ tự nào của các lệnh nguyên tử mà bạn nghĩ rằng nó phải tạo ra. –

1

Từ standard

6,5 (2) Nếu một tác dụng phụ trên một đối tượng vô hướng là unsequenced liên quan đến hoặc là một tác dụng phụ khác nhau trên các đối tượng vô hướng cùng một hoặc một tính toán giá trị sử dụng giá trị của đại lượng vô hướng tương tự đối tượng, hành vi không xác định. Nếu có nhiều thứ tự cho phép của biểu thức phụ của một biểu thức, hành vi không xác định nếu tác dụng không được tuân theo xảy ra trong bất kỳ thứ tự nào. 74)

74) Đoạn này làm cho biểu thức tuyên bố không xác định như

 
      i = ++i + 1; 
      a[i++] = i; 

trong khi cho phép

 
      i = i + 1; 
      a[i] = i; 
Các vấn đề liên quan