2011-11-23 5 views
5

nếu tôi biên dịch mãtại sao vôn bay hơi không được tối ưu hóa ngay cả trong các trường hợp rất đơn giản?

int main() 
{ 
    int i; 
    i = 1; 
    i = 2; 
} 

trong VS với Release và tối ưu hóa, tháo gỡ trông giống như:

int main() 
{ 
    int i; 
    i = 1; 
    i = 2; 
} 
010D1000 xor   eax,eax 
010D1002 ret 

nhưng nếu tôi viết từ "ổn định":

int main() 
{ 
01261000 push  ecx 
    volatile int i; 
    i = 1; 
01261001 mov   dword ptr [esp],1 
    i = 2; 
01261008 mov   dword ptr [esp],2 
} 
0126100F xor   eax,eax 
01261011 pop   ecx 
01261012 ret 

không ai biết tại sao VS lá mã này? là có bất kỳ tác dụng phụ từ nó? đó là mã duy nhất trong chương trình, vậy tại sao trình tối ưu hóa không thể chỉ xóa nó đi?

+23

"Tôi đã nói với nó để X. Tại sao nó X?" – delnan

+6

+1 cho câu hỏi sai lệch được xây dựng tốt. –

+0

Tôi sẽ tưởng tượng nó không có giá trị (MSVC) phát triển thời gian để làm cho tình hình này được tối ưu hóa, vì nó là vô nghĩa để khai báo một biến không tĩnh cục bộ dễ bay hơi. –

Trả lời

11

Từ this trang tài liệu tham khảo:

dễ bay hơi - các đối tượng có thể được sửa đổi bằng các phương tiện không thể phát hiện được bởi trình biên dịch và do đó một số tối ưu hóa trình biên dịch phải được vô hiệu hóa.

4

Trình sửa đổi volatile có nghĩa là biến có thể thay đổi hoặc được đọc ngoài kiểm soát của chương trình trong quá trình biên dịch. Không có gì để được tối ưu hóa.

8

Nếu vôn dễ bay hơi có thể được tối ưu hóa, điều đó sẽ đánh bại mục đích của họ, phải không? Đặt volatile trên một var là nói với trình biên dịch mà bạn biết một cái gì đó nó không. Một cái gì đó có thể xảy ra với var này hoàn toàn nằm ngoài phạm vi của chương trình. Nếu trình biên dịch tối ưu hóa nó đi, nó sẽ làm hỏng những kế hoạch đó.

5

Vâng vì volatile cho trình biên dịch biết rằng biến có thể được truy cập/thay đổi theo cách mà trình biên dịch không thể nhìn thấy. Thường được sử dụng trong phần mềm nhúng, nơi phần cứng ngắt ví dụ có thể thay đổi giá trị của biến.

2

Nếu i được ánh xạ tới sổ đăng ký trên bảng bổ trợ, sẽ rất tệ để trình biên dịch đưa ra giả định về nội dung của nó.

i = 1; 
i = 2; 

Điều này có thể cấp lệnh cho một phần cứng. Bỏ qua lệnh '1' có thể đưa ra một số kết quả khá xấu.