问题
From the C++17 Standard Draft § 3.5.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
Additionally there is an example provided in the standard:
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
}
}
Does the third function declaration extern void f()
receives:
external
linkage ( due to the precedingextern void f()
declaration )internal
linkage ( since the second declaration off()
in the block scope above receives internal linkage from the declaration off()
in the::
global namespace )- Or is it ill-formed because there are more " more than one such matching entity" ?
EDIT
main.cpp
#include <iostream>
extern void g();
void f() { std::cout << "main f() called" << std::endl; }
int main(){
g();
return 0;
}
test.cpp:
#include <iostream>
static void f() { std::cout << " test f() called" << std::endl; }
void g() {
extern void f();
{
extern void f();
f();
}
}
g()
is called in the main()
function in main.cpp
.
Compiled with gcc 5.4.0
g++ -std=c++14 -Wall main.cpp test.cpp
Prints:
main f() called
Thus, gcc obviously treats the call of f()
from within g()
with external
linkage ( calling the definition provided in the main.cpp
file ). Either the comment in the example from the standard is wrong ( the function declaration of #3
has not interal linkage ) or its a compiler bug from gcc
.
回答1:
I don't understand your confusion. The innermost enclosing namespace scope is that of the global namespace; the first and second declarations match in type and name, and hence the outer block-scope declaration just inherits the global declaration's linkage (which is internal due to the static
specifier). The second block-scope declaration is associated with the first one; you get the idea.
来源:https://stackoverflow.com/questions/41978949/linkage-of-function-declared-as-extern-in-block-scope-according-to-the-c17-s