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