này rất hữu ích khi bạn cần phải truy cập vào một biến mà cư trú trong phạm vi một đơn vị dịch thuật, mà không lộ biến bên ngoài trên toàn thế giới (đối với một vài lý do, như tên va chạm, hoặc là biến không nên được truy cập trực tiếp, vì vậy static
được sử dụng để giới hạn phạm vi của nó, nhưng tiêu đề của TU vẫn cần truy cập).
Như một ví dụ, cho phép nói rằng chúng ta có một đơn vị dịch foo.c
, nó chứa:
//foo.c
static int i = 0;
i
không nên thay đổi hoặc trực tiếp truy cập bên ngoài foo.c
Tuy nhiên, foo.h
đến cùng đòi hỏi quyền truy cập vào i
cho một chức năng nội tuyến, nhưng i
không được tiếp xúc với bất kỳ đơn vị dịch nào sử dụng foo.h
, vì vậy chúng tôi có thể sử dụng extern
ở cấp chức năng để chỉ hiển thị nó trong phạm vi IncI
, hàm nội tuyến yêu cầu sử dụng i
:
//foo.h
inline void IncI(int val)
{
extern int i;
i += val;
}
ví dụ thứ hai của bạn là 'cấm' vì trình biên dịch nghĩ rằng bạn đang cố gắng để ràng buộc hai biến khác nhau với tên biểu tượng tương tự, ví dụ: nó tạo ra static i
ở phạm vi địa phương, nhưng tìm kiếm cho extern int i
ở phạm vi toàn cầu, nhưng không tìm thấy nó, bởi vì static i
như ở phạm vi chức năng. một trình biên dịch thông minh hơn sẽ chỉ sửa liên kết đến static i
, cho dù điều này có tuân thủ các tiêu chuẩn mà tôi không biết hay không.
Bây giờ tôi có một C standards document làm việc từ (xấu hổ về tôi Tôi biết ...), chúng ta có thể nhìn thấy những gì lập trường chính thức là (trong C99):
6.2.2 Linkages of identifiers
Section 3:
If the declaration of a file scope identifier for an object or a function contains the storageclass specifier static, the identifier has internal linkage.
Section 4:
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
như vậy, bởi vì static
sẽ gây ra liên kết nội bộ, extern
sẽ đưa liên kết đó vào phạm vi hiện tại. đó cũng là một ghi chú nói rằng điều này có thể gây ra ẩn của các biến:
23) As specified in 6.2.1, the later declaration might hide the prior declaration.
Vì 'i' là extern hoặc local - không thể là cả hai. – Till
không được phép? Đoạn mã thứ hai của bạn chạy hoàn toàn tốt trên gcc (mingw) –
Tôi đang sử dụng gcc 4.1.2 20080704 (Red Hat 4.1.2-51) và tôi nhận được lỗi sau: file1.c: Trong hàm âm thanh: file1.c : 6: error: extern declaration của âiâ sau khai báo không có liên kết file1.c: 5: error: định nghĩa trước đây của âiâ là ở đây – Bruce