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

标签 c

#include <stdio.h>

static i = 5;

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

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

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

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

最佳答案

当您需要访问驻留在另一个翻译单元中的变量时,这很有用,而不需要全局公开外部变量(出于某些原因,例如名称冲突,或者变量不应该 可以直接访问,因此 static 用于限制其范围,但该 TU 的 header 仍需要访问)。

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

//foo.c
static int i = 0;

i 不应在 foo.c 之外更改或直接访问,但是,foo.h 需要访问 i 用于内联函数,但 i 不应暴露给任何使用 foo.h 的翻译单元,因此我们可以使用 extern 在功能级别,仅在 IncI 范围内公开它,需要使用 i 的内联函数:

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

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


现在我有一个 C standards document从(我知道我感到羞耻......)开始工作,我们可以看到官方立场是什么(在 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.

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

23) As specified in 6.2.1, the later declaration might hide the prior declaration.

关于c - 在函数内部将静态变量声明为 extern 有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9686198/

相关文章:

c - 汇编中的无符号整数

c - C 语言螺旋魔方

c - 为什么要在 C 中指定一个带符号的整数?

c - 简单的输入。程序崩溃

c - syslog 存储错误消息的位置

c - 在 C 代码库中查找全局/静态变量的工具

c - 我不明白这个程序是如何工作的

c - 初始化数组/结构的不熟悉语法,寻找解释

c - 为什么我可以在函数内而不是 main 中增加 char 数组位置

c - 流量控制滑动窗口的实现。静态队列(数组)与动态链表哪个更好?