Nó không được xác định bởi vì nó sửa đổi x
hai lần giữa các điểm chuỗi. Tiêu chuẩn nói rằng nó không được xác định, do đó nó không được xác định.
Điều đó nhiều tôi biết.
Nhưng tại sao?
Hiểu biết của tôi là việc cấm điều này cho phép trình biên dịch tối ưu hóa tốt hơn. Điều này có thể có ý nghĩa khi C được phát minh, nhưng bây giờ có vẻ như là một đối số yếu.
Nếu chúng ta tái tạo C ngày hôm nay, chúng ta sẽ làm theo cách này, hay nó có thể được thực hiện tốt hơn?
Hoặc có thể có một vấn đề sâu sắc hơn, khiến cho việc xác định các quy tắc nhất quán cho các biểu thức đó trở nên khó khăn hơn, vì vậy tốt nhất là cấm chúng?
Vì vậy, giả sử chúng tôi đã phát minh lại C ngày hôm nay. Tôi muốn đề xuất các quy tắc đơn giản cho các biểu thức như x=x++
, dường như tôi làm việc tốt hơn các quy tắc hiện có.
Tôi muốn biết ý kiến của bạn về các quy tắc được đề xuất so với các quy tắc hiện có hoặc các đề xuất khác.
Quy tắc đề xuất:
- Giữa các điểm trình tự, thứ tự đánh giá là không xác định.
- Tác dụng phụ diễn ra ngay lập tức.
Không có hành vi không xác định liên quan. Biểu thức đánh giá giá trị này hoặc giá trị đó, nhưng chắc chắn sẽ không định dạng đĩa cứng của bạn (kỳ lạ là tôi chưa bao giờ thấy một triển khai trong đó x=x++
định dạng đĩa cứng).
Biểu thức ví dụ
x=x++
- Được xác định rõ, không thay đổix
.
Đầu tiên,x
được tăng lên (ngay lập tức khix++
được đánh giá), sau đó giá trị cũ của nó được lưu trữ trongx
.x++ + ++x
- Tăngx
hai lần, đánh giá2*x+2
.
Mặc dù một trong hai bên có thể được đánh giá trước, kết quả làx + (x+2)
(bên trái trước) hoặc(x+1) + (x+1)
(bên phải trước).x = x + (x=3)
- Không xác định,x
được đặt thànhx+3
hoặc6
.
Nếu bên phải được đánh giá đầu tiên, đó làx+3
. Nó cũng có thểx=3
được đánh giá đầu tiên, vì vậy nó3+3
. Trong cả hai trường hợp,x=3
phép gán xảy ra ngay lập tức khix=3
được ước tính, do đó giá trị được lưu trữ sẽ bị ghi đè bởi phép gán khác.x+=(x=3)
- Được xác định rõ, đặtx
thành 6.
Bạn có thể lập luận rằng đây chỉ là tốc ký cho biểu thức trên.
Nhưng tôi muốn nói rằng+=
phải được thực hiện saux=3
, và không phải trong hai phần (đọcx
, đánh giáx=3
, thêm và lưu trữ giá trị mới).
Lợi thế là gì?
Một số ý kiến nêu lên điểm tốt này.
Tôi chắc chắn không nghĩ các biểu thức như x=x++
nên được sử dụng trong bất kỳ mã thông thường nào.
Trên thực tế, tôi là nhiều hơn nữa nghiêm ngặt hơn - Tôi nghĩ rằng việc sử dụng chỉ tốt cho x++
trong khi x++;
một mình.
Tuy nhiên, tôi nghĩ các quy tắc ngôn ngữ phải đơn giản nhất có thể. Nếu không, các lập trình viên chỉ không hiểu họ. quy tắc cấm thay đổi một biến hai lần giữa các điểm chuỗi chắc chắn là quy tắc mà hầu hết các lập trình viên không hiểu.
Một quy tắc rất cơ bản là:
Nếu A hợp lệ và B hợp lệ và chúng được kết hợp theo cách hợp lệ, kết quả là hợp lệ.
x
là giá trị L hợp lệ, x++
là biểu thức hợp lệ và =
là cách hợp lệ để kết hợp giá trị L và biểu thức, vậy tại sao x=x++
không hợp pháp?
Tiêu chuẩn C tạo ra một ngoại lệ ở đây và ngoại lệ này làm phức tạp các quy tắc. Bạn có thể tìm kiếm stackoverflow.com và xem ngoại lệ này khiến mọi người bối rối đến mức nào.
Vì vậy, tôi nói - thoát khỏi sự nhầm lẫn này.
=== Tóm tắt câu trả lời ===
Tại sao làm điều đó?
Tôi đã cố gắng giải thích trong phần trên - tôi muốn các quy tắc C đơn giản.Tiềm năng tối ưu hóa:
Điều này có một chút tự do từ trình biên dịch, nhưng tôi không thấy bất cứ điều gì thuyết phục tôi rằng nó có thể quan trọng.
Hầu hết các tối ưu hóa vẫn có thể được thực hiện. Ví dụ,a=3;b=5;
có thể được sắp xếp lại, mặc dù tiêu chuẩn chỉ định thứ tự. Các biểu thức nhưa=b[i++]
vẫn có thể được tối ưu hóa tương tự.Bạn không thể thay đổi tiêu chuẩn hiện có.
Tôi thừa nhận, tôi không thể. Tôi không bao giờ nghĩ rằng tôi thực sự có thể đi trước và thay đổi các tiêu chuẩn và trình biên dịch. Tôi chỉ muốn nghĩ nếu mọi thứ có thể được thực hiện khác đi.
x
cho chính nó và nếu bạn muốn tăng lên,x
bạn chỉ có thể nóix++;
- không cần chuyển nhượng. Tôi muốn nói rằng nó không nên được định nghĩa chỉ vì khó có thể nhớ những gì sẽ xảy ra.