2009-11-06 30 views
10

Tôi có một câu hỏi về đoạn code C sau:Khi nào là không gian ngăn xếp được phân bổ cho các biến cục bộ?

void my_function() 
{ 
    int i1; 
    int j1; 

    // Do something... 

    if (check_something()) 
    { 
     int i2; 
     int j2; 

     // Do something else... 
    } 

    // Do some more stuff... 
} 

Có bất kỳ đảm bảo khi nào không gian ngăn xếp được phân bổ/deallocated cho i2 và j2 hay nó phụ thuộc vào trình biên dịch? Tôi sẽ mong đợi con trỏ ngăn xếp được điều chỉnh khi i2 và j2 đi vào phạm vi và điều chỉnh trở lại khi chúng vượt ra ngoài phạm vi, nhưng sau đó nghĩ rằng một số trình biên dịch có thể chỉ "tối ưu hóa" toàn bộ và tài khoản cho các biến trong phạm vi lồng nhau khi chức năng đầu tiên được nhập vào.

Tôi biết tôi có thể xem mã lắp ráp được tạo bởi trình biên dịch của tôi, nhưng đã tự hỏi liệu việc triển khai có thể được để lại cho trình biên dịch hay không.

Cảm ơn!

+5

Cũng xem xét các biến có thể được cấp cho các thanh ghi ... – unwind

Trả lời

6

Trình biên dịch là miễn phí để làm bất cứ điều gì nó muốn, miễn là ngữ nghĩa của ngôn ngữ là dành. Nói cách khác, i2j2 có thể bị ràng buộc vào các vị trí bộ nhớ trước khi thực thi đạt đến điểm vào của khối của chúng và có thể không bị chặn bất cứ lúc nào miễn là không ảnh hưởng đến ngữ nghĩa của mã của bạn.

8

Không có đảm bảo nào.

Cờ tối ưu hóa khác nhau có khả năng sẽ dẫn đến các phương pháp lưu biến khác nhau.

Trình biên dịch thậm chí có thể tạo 1 hoặc nhiều biến không sử dụng ngăn xếp và giữ chúng trong sổ đăng ký cho toàn bộ thời gian thực hiện hàm.

+0

+! không đảm bảo. –

4

Vì tôi hiểu bạn thậm chí không thể nhận được bất kỳ sự đảm bảo nào các biến này được cấp phát trên ngăn xếp, chúng có thể được lưu trữ trong sổ đăng ký.

gì bạn thực sự có thể ảnh hưởng ở đây:

  • biên dịch Lời khuyên để đặt biến đăng ký bằng cách sử dụng đăng ký từ khóa.

  • biên dịch giúp với địa hóa phạm vi biến bằng cách di chuyển khai đến nơi muộn như bạn có thể:

 
    int f(void) 
    { 
     /* var1 and var2 probably use the same place for storage. */ 
     { 
      int var1; 
      /* ... do something */ 
     } 

     { 
      int var2; 
      /* ... do something */ 
     } 
    } 


  • Thậm chí cho định nghĩa phạm vi chậm trễ khởi tạo:
 
{ 
    int i; /* Yes, you must declare it at the begin of block. 

    /* Do something... */ 

    i = START_VALUE; 
    /* But you need it only here and below... */ 
} 
0

nếu "check_something()" dễ dàng được đánh giá là 0, toàn bộ khối đó sẽ được tối ưu hóa bằng cách sử dụng mức tối ưu hóa đủ cao. Có, nó phụ thuộc vào trình biên dịch. Nói chung, nếu bạn đang kiểm tra giá trị trả lại của một cuộc gọi hàm, nó sẽ không được tối ưu hóa. Cách tốt nhất để tiếp cận điều này là biên dịch nó và thực sự xem xét việc tháo gỡ tệp để xác minh điều bạn nghĩ đang xảy ra thực sự xảy ra.

3

Nếu các biến sẽ được đặt trên ngăn xếp, không gian ngăn xếp được cấp phát ở đầu hàm trước câu lệnh đầu tiên trong hàm.Con trỏ ngăn xếp sẽ được di chuyển lên (hoặc xuống) tổng số byte để lưu trữ tất cả các biến cục bộ.

Các vấn đề liên quan