可能重复:
Static variables in C++
// x.h
int i = 3;
// x1.cpp
#include"x.h"
//...
// x2.cpp
#include"x.h"
//...
上面的代码会给链接器错误。但是,如果我宣布,
//x.h
static int i = 3;
它不会在gcc中给出链接器错误,即使我们有相同的#include
!我们是否为每个static int i;
文件创建了不同的.cpp
?它会导致任何无声链接错误(由于同名)吗?
答案 0 :(得分:4)
编译C代码时,它一次只能是一个“翻译单元”。早期,#include被扩展为引用文件的文本。所以你在静态情况下得到的东西相当于x1.cpp说static int i = 3;
和x2.cpp做同样的事情。在这种情况下,static
大致意味着“不要与其他翻译单位分享。”
所以是的,当你使用static
时,你正在制作两个不同的i
变量,它们彼此无关。这不会导致链接错误。
答案 1 :(得分:4)
int x;
是实体x
的定义。 C ++的One Definition Rule表示,任何使用的变量都应该在程序中只定义一次。因此错误。
static
说x
有内部联系。也就是说,one.cpp
和two.cpp
中出现的x是两个不同的不相关实体。
C ++标准说在这种情况下使用静态是不推荐使用的(根据Steve的评论,在C ++ 0x中它是不推荐的)。匿名命名空间提供了一个更好的选择。
namespace
{
int x;
}
另请注意,与C不同,在C ++中,标量类型的const变量也具有内部链接。那是
const int x = 7; // won't give you an error if included in different source files.
HTH
答案 2 :(得分:3)
我们是否正在创建不同的静态int i;对于每个.cpp文件?
是
是否会导致任何无声链接错误(由于同名)?
没有。由于静态,它们有不同的名称。
如果这不是您想要的行为,则需要在头文件中使用extern
,并将变量分配到一个翻译单元(.cpp
文件)
答案 3 :(得分:2)
static
创建一个仅在单元内可见的全局变量。
如果要在ecompilation单元以上使用变量,请在标题中使用extern
,并在没有extern
的情况下在implmenetation中声明它。
答案 4 :(得分:0)
在第一个代码示例中出现链接器错误,因为i是在两个编译单元中定义和导出的。在第二种情况下,我是静态的,因此没有导出符号,因为静态变量仅在当前编译单元中可见,并且不会导出到链接器。在这种情况下,您有两个独立的变量,都称为i。
答案 5 :(得分:0)
如上所述,代码看起来像多个.cpp文件正在访问i
,而实际上,每个.cpp文件都有自己的副本。这可能会导致误解和错误。
如果您希望只有i
的一个副本,首选的习惯用法是将其包装在x.h
的访问者函数中:
int& GetI() {
static int i = 3; // this initialization only happens once.
return i;
}
如果您执行希望为每个.cpp文件单独复制i
,则更明确的表达方式是在每个.cpp文件中单独声明i
:
namespace {
int i;
}
为了安全起见,将其置于匿名命名空间中,使其无法从其他.cpp文件访问。