#include <stdio.h>
static i = 5;
int main()
{
extern int i;
printf("%d\n",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有人可以提供任何用例来将静态变量声明为函数块中的extern吗?
新: 为什么不允许这样做?
int main()
{
static i = 5;
extern int i;
printf("%d\n",i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当您需要访问驻留在另一个转换单元中的变量而不全局暴露外部变量时(这有点原因,如名称冲突,或者该变量不应该直接访问,因此static用于限制)它的范围,但TU的标题仍然需要访问).
举个例子,假设我们有一个翻译单元foo.c,它包含:
//foo.c
static int i = 0;
Run Code Online (Sandbox Code Playgroud)
i不应该更改或直接访问外部foo.c,但是,foo.h需要访问i内联函数,但i不应该暴露给任何使用的翻译单元foo.h,因此我们可以extern在功能级别使用,仅在范围内公开它IncI,内联函数需要使用i:
//foo.h
inline void IncI(int val)
{
extern int i;
i += val;
}
Run Code Online (Sandbox Code Playgroud)
你的第二个例子是'不允许',因为编译器认为你试图将两个不同的变量绑定到同一个符号名称,即:它创建static iat本地范围,但搜索extern int iat全局范围,但找不到它,因为static i在功能范围.一个更聪明的编译器只会修复与之关联static i,无论这是否遵循我不知道的标准.
既然我有一份C标准文件可供使用(我知道羞耻......),我们可以看到官方立场是什么(在C99中):
6.2.2标识符的链接
第3节:
如果对象或函数的文件范围标识符的声明包含staticclass说明符static,则标识符具有内部链接.
第4节:
对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符的链接与链接相同在先前的声明中指明.如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接.
因此,由于static将导致内部联系,extern将把这种联系带入当前的范围.还有一个脚注说明这可能会导致隐藏变量:
23)如6.2.1中所述,后面的声明可能隐藏先前的声明.