Trang chủ > Uncategorized > C, C++: toán tử ++ và sequence point và side effect

C, C++: toán tử ++ và sequence point và side effect

Chắc ai cũng biết toán tử ++ trong C++ có hai phiên bản:

  • a++ tăng a thêm 1 (nếu a là int), trả về giá trị hiện tại (trước khi tăng) của a,
  • ++a tăng a thêm 1 (nếu a là int), trả về giá trị sau khi tăng của a.

Vậy cho int a = 1 thì 1 + a++ + a++; sẽ cho ra giá trị bao nhiêu? Dễ quá nhỉ, cứ áp dụng quy tắc trên là xong. Đây là một dạng câu hỏi phổ biến mà một số sách C, C++, v.v và một số giáo viên vẫn hay đố.

Tuy nhiên, thực tế dù bạn có áp dụng quy tắc trên, hay chạy thử bằng trình dịch thì kết quả mà bạn có vẫn luôn là một câu trả lời sai. Bởi vì theo đặc tả của C++, chỉ tại các sequence point, ta mới có thể đảm bảo là các side effect (hiệu ứng lề) của biểu thức đã được thực thi, và thứ tự thực thi thường không được đảm bảo. Chẳng hạn:

  • f() + g();: + không phải là sequence point, ; là sequence point. Không thể chắc chắn được là f() hay g() được thực thi trước.
  • f() + g(a++);: Không thể chắc chắn f() hay g(a++) được thực thi trước, nghĩa là không thể chắc chắn f() hay a++ được thực thi trược, nên nếu trong f có thể truy xuất được a thì giá trị của a sẽ là không xác định.
  • Tình huống ban đầu, 1 + a++ + a++;: Tất cả những gì ta có thể chắc chắn là a sẽ được tăng lên 1 hai lần, việc tăng này có thể xảy ra trước hoặc sau bất kì phép + nào trong biểu thức, nên giá trị của biểu thức này là không xác định, và phụ thuộc vào từng trình dịch cụ thể.

Ta kết luận được gì?

  • Đặc tả của các ngôn ngữ lập trình luôn phức tạp hơn ta tưởng rất nhiều, và những người soạn ra nó thực sự là các language lawyer.
  • Đừng cố lồng ghép các biểu thức như trên, bên cạnh việc không xác định giá trị nó còn làm cho mã nguồn trở nên vô cùng rối rắm.
  • Hạn chế side effect, trả về kết quả nên là công việc duy nhất mà một function phải làm. Đây cũng là một nguyên tắc mà lập trình hàm cổ vũ.
  • Đừng đố người khác những biểu thức như thế này😀.
Tags: ,
  1. Tháng Năm 29, 2011 lúc 1:34 sáng

    Thanks bạn

  2. Khách
    Tháng Mười 14, 2011 lúc 9:17 sáng

    ok mem!

  3. Tháng Hai 9, 2014 lúc 11:10 chiều

    Hey there,
    Very useful post! I would like to invite you to visit my blog as well, and read my latest post about sequence points in C and C++.

    http://blog.panqnik.pl/dev/sequence-points-in-c-cpp/

    Best regards,
    panqnik

  1. No trackbacks yet.

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: