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;
}