Hãy xem xét mã đơn giản này:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Bạn có thể thấy rằng không phải gcc
cũng không clang
tối ưu hóa cuộc gọi tiềm năng g
. Theo cách hiểu của tôi là đúng: Máy trừu tượng giả định rằng volatile
các biến có thể thay đổi bất cứ lúc nào (do được ánh xạ phần cứng), do đó, việc liên tục gấp việc false
khởi tạo vào if
kiểm tra sẽ là sai.
Nhưng MSVC loại bỏ g
hoàn toàn cuộc gọi (giữ cho việc đọc và ghi vào volatile
mặc dù!). Đây có phải là hành vi tuân thủ tiêu chuẩn?
Bối cảnh: Thỉnh thoảng tôi sử dụng loại cấu trúc này để có thể bật / tắt đầu ra gỡ lỗi khi đang di chuyển: Trình biên dịch phải luôn đọc giá trị từ bộ nhớ, do đó việc thay đổi biến / bộ nhớ trong quá trình gỡ lỗi sẽ điều chỉnh luồng điều khiển cho phù hợp . Đầu ra MSVC không đọc lại giá trị nhưng bỏ qua nó (có lẽ là do việc gấp liên tục và / hoặc loại bỏ mã chết), điều này tất nhiên đánh bại ý định của tôi ở đây.
Chỉnh sửa:
Việc loại bỏ các lần đọc và ghi
volatile
được thảo luận ở đây: Có cho phép trình biên dịch tối ưu hóa một biến động cục bộ không? (cảm ơn Nathan!). Tôi nghĩ rằng tiêu chuẩn rất rõ ràng rằng những gì đọc và viết phải xảy ra. Nhưng cuộc thảo luận đó không đề cập đến việc liệu trình biên dịch có lấy kết quả của những lần đọc được cấp và tối ưu hóa dựa trên điều đó hay không. Tôi cho rằng điều này chưa được / không xác định trong tiêu chuẩn, nhưng tôi rất vui nếu ai đó chứng minh tôi sai.Tất nhiên tôi có thể tạo
x
một biến không cục bộ để giải quyết vấn đề. Câu hỏi này là nhiều hơn tò mò.