Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当全局变量在头文件中声明为静态时,没有链接器错误_C++_Linker_Static Variables - Fatal编程技术网

C++ 当全局变量在头文件中声明为静态时,没有链接器错误

C++ 当全局变量在头文件中声明为静态时,没有链接器错误,c++,linker,static-variables,C++,Linker,Static Variables,可能重复: 上面的代码将给出链接器错误。但是如果我宣布, //x.h static int i = 3; 它不会在gcc中给出链接器错误,即使我们有相同的#include!我们正在创建不同的静态int i?它是否会导致任何无声链接错误(由于名称相同)?当编译C代码时,它一次是一个“翻译单元”。早期,#include被扩展到引用文件的文本中。因此,在静态情况下得到的等价于x1.cpp,表示static int i=3和x2.cpp执行相同的操作。在这个上下文中,static大致意思是“不要与其

可能重复:

上面的代码将给出链接器错误。但是如果我宣布,

//x.h
static int i = 3;

它不会在gcc中给出链接器错误,即使我们有相同的
#include
!我们正在创建不同的
静态int i.cpp
文件的代码>?它是否会导致任何无声链接错误(由于名称相同)?

当编译C代码时,它一次是一个“翻译单元”。早期,#include被扩展到引用文件的文本中。因此,在静态情况下得到的等价于x1.cpp,表示
static int i=3
和x2.cpp执行相同的操作。在这个上下文中,
static
大致意思是“不要与其他翻译单元共享此内容。”


因此,是的,当您使用
static
时,您正在生成两个不同的
i
变量,它们彼此无关。这不会导致链接错误。

static
创建一个仅在装置内部可见的全局变量

如果要在多个编译单元中使用变量,请在标头中使用
extern
,并在implementation中声明它,而不使用
extern

我们正在创建不同的静态int i;对于每个.cpp文件

它会导致任何无声链接错误(由于相同的名称)

没有。由于静态原因,它们有不同的名称


如果这不是您想要的行为,您需要在头文件中使用
extern
,并将变量分配到一个翻译单元(
.cpp
文件)

int x
是实体
x
的定义。C++的一个定义规则表示,在程序中,任何使用的变量都必须被精确定义一次。因此出现了错误

static
表示
x
具有内部链接。也就是说,出现在
one.cpp
two.cpp
中的x是两个不同的不相关实体

<> P> C++标准称,在这种情况下使用静态(史提夫的注释,在C++中,不被删除)。匿名名称空间提供了一种更好的选择

namespace
{
   int x;
}

还注意到,与C不同,在C++中,标量类型的const变量也有内部链接。就是

const int x = 7; // won't give you an error if included in different source files.

HTH

您在第一个代码示例中得到链接器错误,因为我是在两个编译单元中定义和导出的。在第二种情况下,i是静态的,因此没有导出符号,因为静态变量仅在当前编译单元中可见,而不会导出到链接器。在本例中,您有两个自变量,它们都被称为i。

,正如所写的那样,多个.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文件访问它,以确保安全。

@John,我正在编译.cpp。让它也适用于C++,因为它适用于C和C++。可能的复制品,你不能同时拥有它。它不是C++代码,也不是C代码。只选一个。假如你把代码编译成C++,那么它不是C问题。我真诚地希望你能举出这个例子来演示,全局变量,比如i,是通往调试的道路。地狱是由…@fvu铺就的,我想我们可以假设真正的文件名也不是x.h。请注意,C++0x FDIS不反对这种使用
静态
。而且C++03从未真正解释过匿名名称空间版本的优越性。
namespace {
  int i;
}