C++ C/C++;全局vs静态全局
可能重复:C++ C/C++;全局vs静态全局,c++,c,static,global-variables,C++,C,Static,Global Variables,可能重复: 我对全局变量和静态全局变量之间的区别感到困惑。如果static意味着该变量仅对同一个文件是全局变量,那么为什么在两个不同的文件中使用相同的名称会导致名称冲突 有人能解释一下吗?每个文件中的静态名称不应引起名称冲突。如果你看到了这一点,请发布(简短的)演示代码,以及你正在使用的编译器,以便我们能够正确地验证代码,并假设它是正确的,正确地诋毁编译器 只是FWW,C++中的首选方法是使用匿名命名空间代替: namespace { int not_a_static_variabl
我对全局变量和静态全局变量之间的区别感到困惑。如果static意味着该变量仅对同一个文件是全局变量,那么为什么在两个不同的文件中使用相同的名称会导致名称冲突
有人能解释一下吗?每个文件中的静态名称不应引起名称冲突。如果你看到了这一点,请发布(简短的)演示代码,以及你正在使用的编译器,以便我们能够正确地验证代码,并假设它是正确的,正确地诋毁编译器
只是FWW,C++中的首选方法是使用匿名命名空间代替:
namespace {
int not_a_static_variable;
}
老实说,不,我不能指出这有很多客观的好处,尽管当您创建链接器可用于其他文件的.o
文件时,全局变量(而不是静态变量)存在。因此,如果您有两个这样的文件,则会在a
上发生名称冲突:
a、 c:
因为链接器不知道使用哪个全局a
s
但是,当您定义静态全局变量时,您告诉编译器仅为该文件保留变量,并且不要让链接器知道它。因此,如果将static
(在a
的定义中)添加到我编写的两个示例代码中,就不会出现名称冲突,因为链接器甚至不知道这两个文件中都有a
:
a、 c:
这意味着每个文件都使用自己的a
,而不知道其他文件
作为旁注,其中一个静态
,另一个只要在不同的文件中就可以了。如果两个声明在同一个文件(读取翻译单元)中,一个静态
和一个外部
,请参阅。如果两个变量在不同的文件中声明为静态,则不应引起名称冲突。我刚刚做了一个快速测试,它的工作原理与预期相符。如果它对你不起作用,请把代码贴在它不能像你期望的那样起作用的地方,你期望什么,你得到什么,你正在使用什么编译器。老实说,不,我不能指出它有很多客观的好处…
。。。也许这个主题可以在某种程度上有所帮助:C++11删除了对静态对象的弃用,所以现在这两种方法都不是特别“首选”。@MikeSeymour:这也是真的。@MikeSeymour:删除官方弃用并不意味着它不是首选方法。正如我试图暗示的那样,甚至有几个理由喜欢它,只是不是很多(我在实际代码中遇到的唯一一个原因是希望使用某个东西作为模板参数,至少就我个人而言,我只记得出现过一次或两次)。那么声明一个静态而另一个不是呢?@kissaki,如果这些声明位于不同的文件中,则没有问题。具有静态声明的文件将使用对其他文件不可见的静态变量。所有具有非静态变量声明的文件都将使用共享全局变量。如果这两个声明(一个静态声明和一个外部声明)写入同一个文件(读取翻译单元),请参阅。如何编译a.c
和b.c
?0,0
。没有static
,两个a
s链接在一起,因此它们是相同的a
。在printf
中,您正在打印a
和compute()
的结果,该结果也会修改a
。C表示函数参数的求值顺序未指定。这意味着编译器可以选择先计算a
,然后计算compute()
,或者先计算compute()
然后计算a
。在第一种情况下,您将得到1,0
,在第二种情况下,您将得到0,0
。这两种行为都是有效的,事实上,依赖这两种行为都是编程错误。
#include <stdio.h>
int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
int a;
int compute(void)
{
a = 0;
return a;
}
#include <stdio.h>
static int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
static int a;
int compute(void)
{
a = 0;
return a;
}