Yuk*_*uki 8 c++ clang language-lawyer c++14 c++17
标准N3242(C++ 11草案)和N3797(C++ 14草案)都有相同的段落.
§3.5计划和联系[basic.link]
6
在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.[例如:
Run Code Online (Sandbox Code Playgroud)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
在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接.如果存在具有相同名称和类型的链接的实体的可见声明,忽略在最内部封闭命名空间范围之外声明的实体,则块范围声明声明该实体并接收先前声明的链接.如果存在多个这样的匹配实体,则该程序是不正确的.否则,如果未找到匹配的实体,则块范围实体接收外部链接.如果在翻译单位内,同一实体被宣布具有内部和外部联系,则该程序是不正确的.[例如:
Run Code Online (Sandbox Code Playgroud)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;
}
Run Code Online (Sandbox Code Playgroud)
此代码10 2 2 10在clang-5.0中生成任何-std值c++-11, c++-14, c++17.什么基本上支持C++ 11和14草案的措辞.显然,这并没有改变为带有c++17值的编译错误.在这一点上,clang是否不符合C++ 17?
这是问题426:
这真的是我们想要的吗?C99具有6.2.2.7/7,其给出了在同一翻译单元中具有内部和外部链接的标识符的未定义行为.C++似乎没有等价物.
[...] CWG决定最好使这种联系不匹配的程序形成错误而不是具有不确定的行为.
也就是说,如果名称有联系,则决定一致.实现可能还没有实现.
| 归档时间: |
|
| 查看次数: |
315 次 |
| 最近记录: |