静态变量在该文件中的范围仅在声明它们的位置,如下面的代码所示:
文件1 -
static int a;
文件2 -
extern int a;
这将给出链接错误,因为静态变量a仅在file1中具有范围。但我对以下代码感到困惑:
文件2 -
#include "file1"
extern int a;
这里不会给出任何链接错误。然后它意味着编译器引用在file1中声明的“a”。但是当你调试时,你会发现变量“a”的地址在file1和file2中是不同的。编译器是否在file2中创建另一个全局变量“a”?
完整代码 -
文件temp1.h -
static int w = 9;
class temp1
{
public:
temp1(void);
public:
~temp1(void);
void func();
};
........................ CPP .................
temp1::temp1(void)
{
int e =w;
}
temp1::~temp1(void)
{
}
void temp1::func()
{
}
....................................... 文件2 -
#include "temp1.h"
extern int w;
int _tmain(int argc, _TCHAR* argv[])
{
w = 12;
temp1 obj;
return 0;
}
这里我调试并检查temp1构造函数和file2中的值和地址是不同的。
答案 0 :(得分:7)
static
和extern
与文件无关,它们与翻译单元有关。请记住,当您#include
时,预处理器正在有效地进行复制和粘贴。 static
等等是指该过程的结果,该过程是一个翻译单元。
所以在你的第二个例子中,只有一个翻译单元。所以只有一个变量a
。 [但请注意,这样做是非常糟糕的风格。]
答案 1 :(得分:3)
文件1:
static int a;
file2的:
extern int a;
这里引用了两个变量。第一个是file1
中带有内部链接的变量的声明和定义;第二个是file2
中仅包含外部链接的变量的声明。这不一定会导致错误;在一些翻译单元中使用具有外部链接的变量并且具有由其他翻译单元使用的内部链接的同名变量是完全合法的。只有在a
中使用file2
并且a
中的file2
或程序中的任何其他翻译单元没有定义时,才会出现任何链接错误。< / p>
#include "file1"
extern int a;
在此示例中,您已将两个文件合并为一个翻译单元。变量a
首先在file
中声明并在内部链接中由static
定义,第二个只是重新声明,不会改变以前的联系。在这种情况下,第二个声明是多余的。如果您仍然单独编译这两个文件以及file1
中的file2
,则每个翻译单元(file1
和file1 + file2
)都会有自己的不同变量{{1 }}
请注意,如果您使用了a
后跟extern int a;
,那么这将是一个编译错误,因为第一个声明会声明static int a;
拥有外部链接如果之前没有声明可见,那么第二个声明和定义会导致错误,因为a
隐含的链接会与之前的声明冲突。