Trong c / c ++, các biến phạm vi khối chỉ được xếp chồng lên nhau nếu khối được thực thi?


8

Giả sử điều này:

void func()
{
 ...
 if( blah )
 {
  int x;
 }
 ...
}  

Là không gian dành xriêng trên ngăn xếp ngay lập tức khi funcđược nhập, hoặc chỉ khi khối thực sự được thực thi?
Hay đó là sự lựa chọn của nhà soạn nhạc?
Do C và C ++ hành xử giống nhau về điều này?


1
Đó là việc triển khai được xác định, vì vậy bạn nên xem một vài ví dụ về mã được tạo bởi các trình biên dịch khác nhau để có ý tưởng. Trong cuộc nói chuyện này của Microsoft , người thuyết trình nói ngắn gọn về cái mà anh ta gọi là "stack stack" trên trình biên dịch VisualC ++, có lẽ là một tối ưu hóa để chỉ phân bổ không gian ngăn xếp tối thiểu cần thiết cho mỗi chức năng.
glampert

Câu trả lời:


12

Ai nói trình biên dịch sẽ dành bất kỳ dung lượng nào (chỉ có thể được đăng ký).

Điều này là hoàn toàn không xác định.
Tất cả những gì bạn có thể nói là nó ( x) chỉ có thể được truy cập từ bên trong khối bên trong.

Cách trình biên dịch phân bổ bộ nhớ (trên ngăn xếp nếu nó tồn tại) hoàn toàn phụ thuộc vào trình biên dịch (vì vùng nhớ có thể được sử dụng lại cho nhiều đối tượng (nếu trình biên dịch có thể chứng minh rằng tuổi thọ của chúng không trùng nhau)).

Là không gian cho x dành riêng trên ngăn xếp ngay lập tức khi nhập func

Không xác định được.

hoặc chỉ khi khối thực sự được thực thi?

Không xác định được.
Nhưng nếu xlà một đối tượng lớp thì hàm tạo sẽ chỉ được chạy nếu khối được nhập.

Hay đó là sự lựa chọn của nhà soạn nhạc?

Trình biên dịch thậm chí có thể không phân bổ bộ nhớ.

Do C và C ++ hành xử giống nhau về điều này?

Đúng


3
Tôi sẽ khẳng định rằng việc lo lắng quá nhiều về cách trình biên dịch xử lý điều này sẽ tối ưu hóa sớm cho hầu hết các ứng dụng.
TehShrike

4

Chà, nó thực sự là sự lựa chọn của nhà biên dịch, nhưng những gì tôi đã quan sát thấy là khi tôi biên dịch mà không tối ưu hóa , (đó là những gì chúng ta thường làm để có thể gỡ lỗi mã của mình), trình biên dịch có xu hướng làm mọi thứ khá rõ ràng thời trang cắt, xác định và đáng tin cậy:

  • Trình biên dịch không tối ưu hóa bất kỳ biến cục bộ. (Ngoại trừ, có lẽ, các biến được xác định rõ ràng là register, nhưng điều đó cần được xác minh.)

  • Không gian ngăn xếp cho tất cả các biến cục bộ, bất kể chúng được lồng như thế nào, được dành riêng cùng một lúc khi hàm được nhập.

  • Không gian ngăn xếp được không tái sử dụng trên phạm vi lồng riêng biệt. Điều này có nghĩa là void f(){ { int x; } { int y; } }sẽ phân bổ không gian cho hai intbiến; không gian được phân bổ xsẽ không được sử dụng lại y.

Tất nhiên, nếu bạn kích hoạt tối ưu hóa, tất cả những gì Loki Astari viết trong câu trả lời được chấp nhận là đúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.