Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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++_C++11 - Fatal编程技术网

C++ 块作用域外部声明

C++ 块作用域外部声明,c++,c++11,C++,C++11,C++11标准给出了下面的代码片段(我删除了不相关的代码),并说名称I具有外部链接。(第3.5.6条) 他们为什么这样做?我误解了什么吗?这两个i指的是vs2012中的同一个对象。当我在其他地方使用I时,我得到了一个未解决的外部错误。我不知道vs2012是否支持此功能 编辑: 我认为VS2012的做法是正确的。#3中的i只需要引用具有链接的i。如果编译器找不到,则应在其他翻译单元中定义i。因此,这两个i应该引用上面代码段中的同一个对象 标准中的引用: 如果存在具有链接的实体的可见声明 相同的名称

C++11标准给出了下面的代码片段(我删除了不相关的代码),并说名称
I
具有外部链接。(第3.5.6条)

他们为什么这样做?我误解了什么吗?这两个
i
指的是vs2012中的同一个对象。当我在其他地方使用
I
时,我得到了一个未解决的外部错误。我不知道vs2012是否支持此功能

编辑: 我认为VS2012的做法是正确的。#3中的
i
只需要引用具有链接的
i
。如果编译器找不到,则应在其他翻译单元中定义
i
。因此,这两个
i
应该引用上面代码段中的同一个对象

标准中的引用:

如果存在具有链接的实体的可见声明 相同的名称和类型,忽略在最内层外部声明的实体 块范围声明包含名称空间范围,声明 同一实体并接收上一个声明的链接。如果 未找到匹配的实体,块范围实体接收外部 联系

但是为什么人们需要这个功能呢?

#3
只是一个声明;它表示程序中存在一个名为
i
的变量,该变量具有外部链接,但没有定义该变量。声明允许您在
g
的范围内使用该变量,而不是
#1
中的静态变量

您还需要在包含
g
的命名空间中定义它。在这种情况下,它必须位于不同的转换单元中,这样它就不会与同名的静态变量冲突

需要说明的是,这里有两个不同的变量称为
i
,如示例后面的段落所述<这里定义了代码>#1
#3
仅为声明,需要单独定义。

#3
仅为声明;它表示程序中存在一个名为
i
的变量,该变量具有外部链接,但没有定义该变量。声明允许您在
g
的范围内使用该变量,而不是
#1
中的静态变量

static int i = 0; // #1
void g() {
    extern int i; // #3 external linkage
}
您还需要在包含
g
的命名空间中定义它。在这种情况下,它必须位于不同的转换单元中,这样它就不会与同名的静态变量冲突

需要说明的是,这里有两个不同的变量称为
i
,如示例后面的段落所述<这里定义了代码>#1<代码>#3仅声明,需要单独定义

static int i = 0; // #1
void g() {
    extern int i; // #3 external linkage
}
第一个
static
i
是一个声明,仅在当前源文件中可见

extern int i; 
告诉编译器我不是指这个
static I
,而是指在其他地方定义的另一个
I
。如果您没有在其他地方(在另一个翻译单元中)定义它,您将得到未定义的引用

这不会破坏ODR,因为这(静态的
static
i
是静态的(仅在本单元中可见)

第一个
static
i
是一个声明,仅在当前源文件中可见

extern int i; 
告诉编译器我不是指这个
static I
,而是指在其他地方定义的另一个
I
。如果您没有在其他地方(在另一个翻译单元中)定义它,您将得到未定义的引用

这不会破坏ODR,因为这(静态的
static
i
是静态的(仅在本单元中可见)

我会给你一个
inti

static int i=0
不是承诺的变量,您必须在该
extern
变量声明可见的其他地方声明一个
inti

换句话说,
extern-int-i
静态int i=0是两个不相关的变量

我会给你一个
inti

static int i=0
不是承诺的变量,您必须在该
extern
变量声明可见的其他地方声明一个
inti


换句话说,
extern-int-i
静态int i=0
是两个不相关的变量。

但实际上这两个
i
引用的是同一个对象(至少在vs2012中)。如果是这样,那么编译器就错了。示例后面的段落清楚地解释了它们是分开的。它开始于“在这个程序中有三个名为
i
的对象。”@Mike(OP)你说VS2012抱怨一个未解析的符号(即带有外部链接的
i
)。这意味着它们不是相同的
i
@huskerhad,我的意思是如果我在其他地方使用该名称,我会出错。这听起来不像是解释为什么
i
具有外部链接,即使它被定义为在
\1
具有内部链接。原理是什么?但实际上这两个
i
引用的是同一个对象(至少在vs2012中)。如果是这样,那么编译器就错了。示例后面的段落清楚地解释了它们是分开的。它开始于“在这个程序中有三个名为
i
的对象。”@Mike(OP)你说VS2012抱怨一个未解析的符号(即带有外部链接的
i
)。这意味着它们不是相同的
i
@huskerhad,我的意思是如果我在其他地方使用该名称,我会出错。这听起来不像是解释为什么
i
具有外部链接,即使它被定义为在
\1
具有内部链接。理由是什么?这不是is C++11§3.5p6中的示例。实际示例包含一个额外的块范围
inti,这就是