标准
N3242
(C++ 11草案)
N3797
(C++ 14草案)都有同一段落。
§3.5程序和链接[基本链接]
六
块作用域中声明的函数名和块作用域外部声明的变量名
声明具有链接。如果存在具有相同名称和
类型,忽略在最内部封闭命名空间范围外声明的实体,块范围声明
声明同一实体并接收上一声明的链接。如果有不止一个这样的
匹配实体时,程序格式错误。否则,如果找不到匹配的实体,则块范围实体
接收外部链接。[示例:
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
}
}
有三个物体叫我
在这个程序中。由
全局范围内的声明(行1),由行2上的声明引入的具有自动存储持续时间且没有链接的对象。
以及由第3行声明引入的具有静态存储持续时间和外部链接的对象。
结束示例
]
我觉得有点问题
i
对象示例,它不支持前面段落中所说的内容,对吗?
我认为一定是两个
我
对象,一个具有内部链接(1和3),另一个不具有链接(2)。
我说的对吗?这是标准中的错误吗?这个例子是错误的?
相比之下,标准
N4659
(C++ 17草案)在我看来更正确。
§6.5程序和链接[基本链接]
六
块作用域中声明的函数名和块作用域声明的变量名
外部声明具有链接。如果存在具有相同名称和
类型,忽略在最内部封闭命名空间范围外声明的实体,块范围声明
声明同一实体并接收上一声明的链接。如果有不止一个这样的
匹配实体时,程序格式错误。否则,如果找不到匹配的实体,则块范围实体
接收外部链接。如果在翻译单元内,同一实体同时声明为内部实体和
外部链接,程序格式错误。[示例:
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, ill-formed
}
}
如果没有第2行的声明,第3行的声明将与第1行的声明链接。
但是,由于具有内部链接的声明是隐藏的,因此3被赋予外部链接,使
程序格式错误。
结束示例
]
一些测试
static void f();
static int i = 10; // #1
void g() {
extern void f(); // internal linkage
std::cout << i << std::endl;
int i = 2; // #2 i has no linkage
std::cout << i << std::endl;
{
extern void f(); // internal linkage
std::cout << i << std::endl;
extern int i; // #3 external linkage
std::cout << i << std::endl;
}
}
int main() {
g();
return 0;
}
此代码生成
10 2 2 10
在Clang-5.0中
-std
值来自
c++-11, c++-14, c++17
.
基本上支持C++ 11和14草稿的措辞。
显然,这并没有变为编译错误
c++17
值。CLAN在这一点上不符合C++ 17吗?