相关疑难解决方法(0)

C++块范围外部声明链接,混淆C++标准解释

标准N3242(C++ 11草案)和N3797(C++ 14草案)都有相同的段落.

§3.5计划和联系[basic.link]

6

在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.[例如:

 static void f();
 static int i = 0; // #1
 void g() {
     extern void f(); // internal linkage
     int i; // #2 i has no linkage
     {
         extern void f(); // internal linkage
         extern int i; // #3 external linkage
     }
 }
Run Code Online (Sandbox Code Playgroud)

在这个程序中有三个名为i的对象.具有内部链接的对象由全局范围内的声明引入(第1行),具有自动存储持续时间的对象并且没有由第2行上的声明引入的链接,以及具有静态存储持续时间和由声明引入的外部链接的对象在第3行. - 结束例子]

我觉得i对象示例有问题,它不支持之前段落中的内容,对吧?在我看来,它必须是两个i对象,一个具有内部链接(#1和#3),另一个没有链接(#2).我对么?这是标准中的错误,这个例子是错的吗?

相比之下,标准N4659(C++ 17草案)在我看来更正确.

§6.5计划和联系[basic.link]

6

在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.如果在翻译单位内,同一实体被宣布具有内部和外部联系,则该程序是不正确的.[例如:

static void f();
static int i = 0; // #1
void g() …
Run Code Online (Sandbox Code Playgroud)

c++ clang language-lawyer c++14 c++17

8
推荐指数
1
解决办法
315
查看次数

标签 统计

c++ ×1

c++14 ×1

c++17 ×1

clang ×1

language-lawyer ×1