Thứ nhất, hiện đại, C++ đã chuyển từ cũ (không đầy đủ) khái niệm "điểm chuỗi" để khái niệm mới về "trình tự" (tức là "được sắp xếp trước", "được sắp xếp theo trình tự sau"). Mặc dù i = i++
vẫn chưa được xác định, i = ++i
thực sự được xác định hoàn hảo ngay bây giờ. Các quy tắc sắp xếp thứ tự trong nhiều toán tử trả về bằng lvalue đã được làm lại.
Thứ hai, phiên bản của bạn được an toàn theo đặc điểm kỹ thuật cũ cũng như trong phiên bản mới. Việc sửa đổi i
bên trong chức năng được "cách ly" một cách an toàn khỏi nhiệm vụ sang i
bên ngoài. Trong các điểm chuỗi đặc điểm kỹ thuật cổ điển ở đầu và ở cuối hàm, hãy tách riêng các sửa đổi (và đọc) của i
khỏi nhau. Các quy tắc sắp xếp thứ tự mới duy trì cùng mức độ bảo vệ.
Một ví dụ minh họa việc bảo vệ được cung cấp bởi một cuộc gọi chức năng có thể trông như sau
int inc(int &i) { return i++; }
...
int i = 1;
int r1 = i++ * i++ * i++;
// Undefined behavior because of multiple unsequenced side effects
// applied to the same variable
int r2 = inc(i) * inc(i) + inc(i);
// No UB, but order of evaluation is unspecified. Since the result
// depends on the order of evaluation, it is unspecified
int r3 = inc(i) + inc(i) + inc(i);
// Perfectly defined result. Order of evaluation is still unspecified,
// but the result does not depend on it
gì trình biên dịch nói? – tristan
@tristan thường, trình biên dịch không nói gì về UB. – user2079303
gcc có tùy chọn '-Sách-điểm' – tristan