local/block-scope 有 extern 和没有 extern 的函数声明之间的区别

Difference between local/block-scope declaration of function with extern and without it

在 C++ 中,extern(后面不跟语言链接字符串文字)似乎对命名空间范围 (Difference between declaration of function with extern and without it) 的函数声明没有影响。但它对块作用域函数声明有任何影响吗?或者没有 extern 的局部函数声明总是等同于带有 extern 的局部函数声明?

namespace {
  void f() {
     extern void g(); // has external linkage
     g();
  }
  void f2() {
     void g();        // always the same, as if, without extern
     g();
  }
}

谢谢!

一个函数是否有 extern 说明符,在任何情况下它都有外部链接(如果它没有明确声明为有内部链接)。

但是,局部函数声明可以隐藏外部作用域中同名的其他函数声明。

考虑以下演示程序

#include <iostream>

void f( int ) { std::cout << "F( int )" << std::endl; }
void f( short ) { std::cout << "f( short )" << std::endl; }

int main() 
{
    void f( short );

    f( 10 );

    return 0;
}

它的输出是

f( short )

如果注释局部声明,则输出将是

F( int )

这里的规则来自[basic.link]:

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.

所以有和没有 external 的块作用域函数声明没有区别。但请注意有趣的例子:

static void f();

void g() {
    extern void f(); // internal linkage
}

在这里,块范围 f 重新声明 ::f 并接收相同的链接:内部。尽管它被标记为 extern。但是 extern 关键字的存在与否并不重要