在函数内部声明静态变量作为extern有什么用?

#include  static i = 5; int main() { extern int i; printf("%d\n",i); return 0; } 

有人可以提供任何用例来将静态变量声明为函数块中的extern吗?

新:为什么不允许这样做?

 int main() { static i = 5; extern int i; printf("%d\n",i); return 0; } 

当您需要访问驻留在另一个转换单元中的变量时,这非常有用,而不会全局暴露外部变量(由于某些原因,如名称冲突,或者应该直接访问该变量,因此static用于限制其范围,但TU的标题仍然需要访问权限)。

举个例子,假设我们有一个翻译单元foo.c ,它包含:

 //foo.c static int i = 0; 

i不应该在foo.c之外更改或直接访问,但是, foo.h需要访问i以获取内联函数,但i不应该使用foo.h向任何翻译单元公开,所以我们可以使用在function级别的extern ,只在IncI的范围内公开它,内联函数需要使用i

 //foo.h inline void IncI(int val) { extern int i; i += val; } 

你的第二个例子是’不允许’,因为编译器认为你试图将两个不同的变量绑定到同一个符号名,即:它在本地范围创建static i ,但是在全局范围内搜索extern int i ,但是没有’找到它,因为static i在函数范围。 一个更聪明的编译器只会修复与static i的链接,无论这是否遵循我不知道的标准。


既然我有一份C标准文件可供使用(我知道羞耻……),我们可以看到官方的立场是什么(在C99中):

6.2.2标识符的链接

第3节:

如果对象或函数的文件范围标识符的声明包含staticclass说明符static,则标识符具有内部链接。

第4节:

对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符的链接与链接相同在先前声明中指明。 如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。

因此,因为static会导致内部联系,所以extern会将这种联系带入当前范围。 还有一个脚注说明这可能会导致隐藏变量:

23)如6.2.1中所述,后面的声明可能隐藏先前的声明。

在第二种情况下,您告诉编译器您有一个静态(本地)变量i和另一个在其他地方定义的(全局)变量i