2013-06-13 21 views
12

Một đồng nghiệp đang làm một số xét mã, và anh đang chứng kiến ​​nhiều khai báo biến tĩnh tương tự như sau:Có lý do chính đáng để khởi tạo biến tĩnh trên mọi cuộc gọi đến hàm được xác định không?

void someFunc(){ 

    static int foo; 
    static int bar; 
    static int baz; 

    foo = 0; 
    bar = 0; 
    baz = 0; 

    /* 
     rest of the function code goes here 
    */ 

} 

câu hỏi của chúng tôi là, Liệu các lập trình viên viết mã này chỉ đơn giản là không rõ ràng về khái niệm về một tĩnh biến, hoặc là có một số lý do thông minh để làm điều này có mục đích?

Nếu có bất kỳ sự khác biệt nào, môi trường là một vi điều khiển được nhúng và trình biên dịch là GCC.

+6

Khi tuyên bố như tĩnh, nó tránh lưu trữ các biến trong ngăn xếp. Vì vậy, giảm thiểu kích thước ngăn xếp cũng có thể là một lý do .. – VoidPointer

+2

Nếu chúng đã cố ý, ví dụ: để giảm mức sử dụng ngăn xếp, thì chúng nên giải thích rằng trong nhận xét. –

Trả lời

13

Nếu nó không phải là một hệ thống nhúng, bạn có lẽ sẽ đúng: Tôi sẽ đặt cược rằng các lập trình viên đã không rõ ràng về các khái niệm về các tĩnh, và phải có nghĩa là để viết những dòng này:

static int foo = 0; 
static int bar = 0; 
static int baz = 0; 

Tuy nhiên, trong một hệ thống nhúng, họ có thể đã sử dụng static để tránh phân bổ các biến trong bộ nhớ tự động (nghĩa là trên ngăn xếp). Điều này có thể tiết kiệm một vài chu kỳ CPU, vì địa chỉ của biến tĩnh sẽ được "nướng vào" mã nhị phân của phương thức được biên dịch.

+7

Nó cũng tiết kiệm không gian ngăn xếp, mà tôi nghĩ rằng có lẽ là điểm quan trọng hơn. Nó sẽ tiết kiệm bộ nhớ tổng thể, nếu chức năng đệ quy (mặc dù điều đó sẽ làm cho việc sử dụng các biến tĩnh phức tạp). Nếu kích thước ngăn xếp là rất hạn chế, nó có thể là cần thiết để tránh tràn ngăn xếp. – morningstar

+0

@morningstar một nhận xét rất tốt để trả lời rất tốt cho một câu hỏi rất tốt. –

+2

gọi hàm đệ quy sử dụng biến tĩnh? tốt hơn là một lý do rất tốt – levengli

2

Trong ngữ cảnh này, bộ nhớ tĩnh chỉ được phân bổ một lần. Vấn đề với mã này là khởi tạo. Nếu nó được đặt lại ở mọi lần thực hiện, các biến này sẽ tồn tại trên ngăn xếp.

0

Thực hiện chức năng như hiện tại, làm giảm lợi ích của static. 2 lý do chính để sử dụng static là:

  1. Có một biến duy trì giá trị của nó giữa các cuộc gọi đến các chức năng tương tự
  2. Tránh phân bổ bộ nhớ trên stack

gắn liền @dasblinkenlight câu trả lời để thứ 2 tùy chọn, tuy nhiên không có ai trong lập trình nhúng người sẽ lãng phí bộ nhớ không thể khôi phục để tiết kiệm 24 byte (giả sử rằng int là 32 byte trên kiến ​​trúc của bạn) trên ngăn xếp. Lý do là trình biên dịch sẽ thao tác con trỏ ngăn xếp đến hàm bất kể, và do đó không có gì để lưu (về chu kỳ) từ việc không có nó đẩy SP khác 24 byte.

Lưu ý rằng, chúng tôi còn lại với tùy chọn mà người dùng muốn duy trì một số thông tin liên quan đến foo, barbaz giữa các cuộc gọi. Nếu đây không phải là trường hợp, những gì bạn đang xem là lập trình xấu.

+0

Trong khi sự cân bằng giữa ngăn xếp và phân đoạn dữ liệu ít có ý nghĩa trong hầu hết các vi 32-bit, nó có thể có ý nghĩa trong một trường hợp tài nguyên rất hạn chế chẳng hạn như nhiều bộ vi xử lý PIC hoặc bộ vi xử lý AVR. Các PIC nhỏ nhất có một ngăn xếp phần cứng rất nông và chỉ có vài trăm byte tổng dung lượng RAM. Tất nhiên, hầu hết mã cho môi trường giới hạn đó chỉ đơn giản là sử dụng các biến toàn cục. Thậm chí còn có một số lõi ARM trong hệ thống trên một gói chip có RAM rất nhỏ (và số pin). – RBerteig

0

lợi ích tĩnh. là:

Có một biến duy trì giá trị của nó giữa các cuộc gọi với cùng chức năng Tránh phân bổ bộ nhớ trên stack

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