可能是重复问题:
静态变量与全局变量
我对全局变量和静态全局变量之间的区别感到困惑。如果静态意味着此变量仅针对同一文件是全局的,那么为什么在两个不同的文件中相同的名称会导致名称冲突?
有人能解释一下吗?
可能是重复问题:
静态变量与全局变量
我对全局变量和静态全局变量之间的区别感到困惑。如果静态意味着此变量仅针对同一文件是全局的,那么为什么在两个不同的文件中相同的名称会导致名称冲突?
有人能解释一下吗?
全局变量(非static
)在创建.o
文件时可供链接器在其他文件中使用。因此,如果您有两个类似于以下的文件,则会在a
上发生名称冲突:
a.c:
#include <stdio.h>
int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
int a;
int compute(void)
{
a = 0;
return a;
}
a
。a
的定义中添加 static
,你将不会遇到名称冲突的问题,因为链接器甚至不知道这两个文件中有一个名为 a
的变量:#include <stdio.h>
static int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
static int a;
int compute(void)
{
a = 0;
return a;
}
这意味着每个文件都可以使用自己的a
,而不知道其他文件中的变量。
另外,只要它们在不同的文件中,一个变量声明为static
,另一个则未声明也是可以的。如果两个声明在同一个文件(翻译单元)中,其中一个声明为static
,另一个声明为extern
,请参阅此答案。
int a;
,在Linux上使用gcc 5.2.1,我得到的变量被指定为“公共符号”(你可以使用nm
查看此信息。nm
用C
标记它)。int a = 0;
被放置在BSS中(nm
用B
标记它),而int a = something_else;
被放置在“初始化数据”中(nm
用D
标记它)。显然,GNU ld
规则是,C
中的符号与B
和D
中的符号链接。我无法确定其他编译器和链接器是否显示此行为。 - Shahbaza
,你会得到链接错误。 - Shahbaz每个文件中静态的名称不应该导致名称冲突。如果你遇到了这种情况,请提供一个简短的演示代码,以及您正在使用的确切编译器,以便我们可以正确验证代码,假设它是正确的,妥善批评编译器。
只是顺带一提,C++ 中首选的方法是使用匿名命名空间:
namespace {
int not_a_static_variable;
}