标准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 } }
三个名为i的对象 在这个程序中。具有内部链接的对象由 全局作用域(第1行)中的声明,具有自动存储期限且第2行中的声明未引入任何链接的对象 ,以及第3行中的声明引入的具有静态存储持续时间和外部链接的对象。 -结束示例 ]
我觉得i
对象示例出了点问题,它不支持前面段落中的内容,对吗?
我认为它必须是两个i
对象,一个具有内部链接(#1和#3),而一个没有链接(#2)。
我对么?是标准中的错误,示例是错误的吗?
相反,我认为标准N4659(C ++ 17草案)更正确地说明了这一点。
§6.5程序和链接[basic.link]
¶6
在块作用域中声明的函数的名称和在块作用域中声明的变量的名称 外部声明具有链接。如果存在具有相同名称的链接的实体的可见声明,并且 类型,忽略在最内层的封闭命名空间范围之外声明的实体,即块范围声明 声明同一实体,并接收先前声明的链接。如果不止一个这样的 匹配实体,则程序格式不正确。否则,如果找不到匹配的实体,则块作用域实体 接收外部链接。如果在翻译单元内使用内部和内部声明了相同的实体 外部链接,程序格式不正确。 [示例:
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;
}
此代码在clang-5.0中使用来自10 2 2 10
的{{1}}值生成-std
。
基本上支持C ++ 11和14草案措辞的内容。
显然,这并没有变为具有c++-11, c++-14, c++17
值的编译错误。此时clang是否不符合C ++ 17?
答案 0 :(得分:5)
那是问题426:
这真的是我们想要的吗? C99具有6.2.2.7/7,它提供了未定义的行为,使标识符与内部和外部链接出现在同一翻译单元中。 C ++似乎没有它。
[…] CWG决定,将程序设计成具有这种形式的链接失配,而不是具有不确定的行为。
也就是说,决定一个名称具有链接,则该名称应保持一致。实现可能尚未实现。