2011-06-05 114 views
3

静态变量具有文件内部的范围仅在那里它们被被声明,如示于以下代码:静态成员变量文件范围

file1-

static int a; 

file2-

extern int a; 

这会导致链接错误,因为静态变量a仅在file1中具有范围。但我很困惑与下面的代码:

file2-

#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() 
{ 
} 

............................ ........... file2-

#include "temp1.h" 

extern int w; 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    w = 12; 

    temp1 obj; 
    return 0; 
} 

在这里,当我调试和检查temp1构造函数和file2中的值和adrress是不同的。

+0

除非'temp1.h'包含自身,否则该代码不完整(或可能不正确)。你能显示'temp1.h'的内容吗? – 2011-06-05 14:03:29

+0

发布编辑,我想我的回答完全回答你的问题。在两个翻译单元中,'w'具有_internal linkage_,因为头文件中包含的'w'是'static int w = 9;'声明的第一个声明。这意味着两个翻译单元都有自己独特的独立“w”。 – 2011-06-05 14:35:26

+0

所以这意味着第二个翻译单元也定义变量w,即使它是外部的(因为它不会导致重新定义,因为第一个定义是翻译单元1中的内部连接)? – 2011-06-05 15:13:23

回答

3

文件1:

static int a; 

文件2:

extern int a; 

这里有参考两个变量。首先是内部联动file1中的一个变量的声明和定义;第二个是仅有一个变量的声明外部链接file2。这不一定会导致错误;在一些翻译单位中使用具有外部连接的变量以及由其他翻译单位使用内部连接的同名变量是完全合法的。任何链接错误只会在file2中使用afile2中的a或程序中的任何其他翻译单元没有定义。

#include "file1" 
extern int a; 

在这个例子中,你已经将两个文件组合成一个单一的翻译单元。变量a首先在file中用内部链接进行声明和定义,因为static,第二个只是重新声明,它不会改变以前的链接。在这种情况下,第二个声明是多余的。如果您仍然单独编译这两个文件以及从file2包括file1,那么每个翻译单元(file1file1 + file2)将具有其自己的独特变量,称为a

需要注意的是,如果你使用过之后static int a;extern int a;那么这将是一个编译错误,因为第一个声明将宣布a外部链接如果没有事先声明是可见的,那么第二个声明和定义会导致错误,因为static int a;暗示的链接会与先前的声明发生冲突。

+0

现在这对我有意义。谢谢Charles的澄清。 – 2011-06-06 14:32:15

7

staticextern不符合文件做,他们与翻译单元做。请记住,当你的某些东西,预处理器正在有效地进行复制和粘贴。 static等指的是该过程的结果,该过程是翻译单元。

所以在第二个例子中,只有一个翻译单元。所以只有一个变量a[但要注意,做这种方式被认为是非常不好的风格。]

+0

是的,这是一个翻译单元。但为什么varaibale“a”的地址在两个文件中都不同? – 2011-06-05 13:39:47

+0

@Ghanshyam:我想你必须编辑你的问题来显示一个*完整的*,*可编译的*例子来展示你的意思。 – 2011-06-05 13:41:02

+0

下面是代码 – 2011-06-05 13:53:35