volatile có hai ý nghĩa chính:
- Giá trị có thể thay đổi bên ngoài luồng kiểm soát của chương trình. Do đó, mỗi khi trình biên dịch đọc giá trị biến, nó không được giả định giá trị giống lần đọc trước hoặc lần ghi trước, mà phải đọc lại thực tế từ bộ nhớ.
- Việc ghi giá trị vào biến volatile là "side effect" có thể quan sát từ bên ngoài. Trình biên dịch không được loại bỏ hành động ghi giá trị. Ví dụ: nếu ghi hai giá trị liên tiếp, trình biên dịch phải thực sự ghi cả hai lần.
Ví dụ minh họa
i = 2;
i = i;
Trình biên dịch phải: lưu số 2, đọc biến i, lưu giá trị vừa đọc vào i. Không được tối ưu hóa bỏ qua bất kỳ bước nào.
Khi nào dùng volatile?
- Đăng ký phần cứng (hardware registers) – giá trị thay đổi bởi thiết bị ngoại vi.
- Biến chia sẻ giữa ngắt (ISR) và mã chính.
- Biến chia sẻ giữa các thread (kết hợp với atomic/mutex).
- Bộ nhớ ánh xạ (memory-mapped I/O).
volatile KHÔNG phải
- Thay thế cho
std::atomic(không đảm bảo atomicity hay memory ordering). - Cơ chế đồng bộ hóa thread an toàn.
Tham khảo chi tiết: Understanding volatile qualifier in C/C++