无法理解 [basic.link]/6 C++14 示例中的声明 #3
Can't understand the declaration #3 in the Example of [basic.link]/6 C++14
[basic.link]/6
The name of a function declared in block scope and the name of a
variable declared by a block scope extern
declaration have linkage.
If there is a visible declaration of an entity with linkage having the
same name and type, ignoring entities declared outside the innermost
enclosing namespace scope, the block scope declaration declares that
same entity and receives the linkage of the previous declaration. If
there is more than one such matching entity, the program is
ill-formed. Otherwise, if no matching entity is found, the block scope
entity receives external linkage.[ Example:
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
}
}
There are three objects named i
in this program. The object with internal linkage introduced by the declaration in global scope (line #1), the object with automatic storage duration and no linkage introduced by the declaration on line #2, and the object with static storage duration and external linkage introduced by the declaration on line #3. —end example ]
我对这段有两条评论:
- 全局范围内的
static int i = 0;
声明 在包含声明 extern int i;
(#3) 的块内不可见 。因此我们只能说后一个声明具有外部链接,即我们不能将它与声明#1 关联。
- 否则,如果声明
static int i;
被声明 #3 视为可见,则根据段落中的文本,块作用域声明声明相同的实体并接收先前声明的链接,即内部链接,而不是外部链接,如示例中所述。
我在这里错过了什么?
这受制于 active issue 426 说:
An example in 3.5 [basic.link] paragraph 6 creates two file-scope
variables with the same name, one with internal linkage and one with
external.
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
}
}
Is this really what we want? C99 has 6.2.2.7/7, which gives undefined
behavior for having an identifier appear with internal and external
linkage in the same translation unit. C++ doesn't seem to have an
equivalent.
最初的提议是让它成为未定义的行为:
We agree that this is an error. We propose to leave the example but
change the comment to indicate that line //3 has undefined behavior,
and elsewhere add a normative rule giving such a case undefined
behavior.
但最后两条评论说:
According to 3.5 [basic.link] paragraph 9, the two variables with
linkage in the proposed example are not “the same entity” because they
do not have the same linkage. Some other formulation will be needed to
describe the relationship between those two variables.
和:
The CWG decided that it would be better to make a program with this
kind of linkage mismatch ill-formed instead of having undefined
behavior.
最新的评论没有提出新的措辞,而且自 2006 年以来就没有更新过,所以目前的想法充其量只能说这是错误的。
参考 C99 标准草案 6.2.2.7/7
说:
If, within a translation unit, the same identifier appears with both internal and external
linkage, the behavior is undefined.
[basic.link]/6
The name of a function declared in block scope and the name of a variable declared by a block scope
extern
declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage.[ Example: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 } }
There are three objects named
i
in this program. The object with internal linkage introduced by the declaration in global scope (line #1), the object with automatic storage duration and no linkage introduced by the declaration on line #2, and the object with static storage duration and external linkage introduced by the declaration on line #3. —end example ]
我对这段有两条评论:
- 全局范围内的
static int i = 0;
声明 在包含声明extern int i;
(#3) 的块内不可见 。因此我们只能说后一个声明具有外部链接,即我们不能将它与声明#1 关联。 - 否则,如果声明
static int i;
被声明 #3 视为可见,则根据段落中的文本,块作用域声明声明相同的实体并接收先前声明的链接,即内部链接,而不是外部链接,如示例中所述。
我在这里错过了什么?
这受制于 active issue 426 说:
An example in 3.5 [basic.link] paragraph 6 creates two file-scope variables with the same name, one with internal linkage and one with external.
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 } }
Is this really what we want? C99 has 6.2.2.7/7, which gives undefined behavior for having an identifier appear with internal and external linkage in the same translation unit. C++ doesn't seem to have an equivalent.
最初的提议是让它成为未定义的行为:
We agree that this is an error. We propose to leave the example but change the comment to indicate that line //3 has undefined behavior, and elsewhere add a normative rule giving such a case undefined behavior.
但最后两条评论说:
According to 3.5 [basic.link] paragraph 9, the two variables with linkage in the proposed example are not “the same entity” because they do not have the same linkage. Some other formulation will be needed to describe the relationship between those two variables.
和:
The CWG decided that it would be better to make a program with this kind of linkage mismatch ill-formed instead of having undefined behavior.
最新的评论没有提出新的措辞,而且自 2006 年以来就没有更新过,所以目前的想法充其量只能说这是错误的。
参考 C99 标准草案 6.2.2.7/7
说:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.