2

It appears that in C++ extern (NOT followed by a language-linkage string literal) makes no difference on function declarations at namespace scope (Difference between declaration of function with extern and without it). But does it have any effect whatsoever on block scope function declarations? Or is a local function declaration without extern always equivalent to one with extern?

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

Thanks!

Community
  • 1
  • 1

2 Answers2

2

The rules here come from [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.

So there is no difference between a block scope function declaration with and without external. But note the interesting example:

static void f();

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

Here, the block scope f redeclares ::f and receives its same linkage: internal. Even though it's marked extern. But the presence of absence of the extern keyword is immaterial

Barry
  • 286,269
  • 29
  • 621
  • 977
1

Whether a function has the extern specifier or not in any case it has external linkage (if it is not explicitly declared as having internal linkage).

However a local function declaration can hide other function declarations with the same name in the outer scope.

Consider the following demonstrative program

#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;
}

Its output is

f( short )

If to comment the local declaration then the output will be

F( int )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I feel that this answer highlights the use of local function declarations more than answering whether there are any scenarios that the presence or absence of extern on a local function declaration matters? Or am I missing something? Also any references to the C++ standard will be appreciated. Thanks! – EulersRainbow Jul 26 '16 at 11:31
  • @EulersRainbow A local declaration can be useful when there is a conflict between your function declaration and a declaration of a function with the same name in some library that is when the name resolution is ambiguios. As for the reference to the Standard unfortunately I have no copy of the Standard or its draft by hand. – Vlad from Moscow Jul 26 '16 at 11:32
  • Thanks. I think I understand their benefit - and your example does a great job of highlighting the benefit of local declarations. But the question I am more interested in is: Based on the C++ standard, is their truly no difference ever if I add 'extern' to the local function declaration? – EulersRainbow Jul 26 '16 at 11:37
  • @EulersRainbow It has a difference for object declarations. – Vlad from Moscow Jul 26 '16 at 11:38
  • @EulersRainbow The default linkage for functions is `extern`. This fact is not affected by where the functions are declared. Perhaps this answer should say that more explicitly. – underscore_d Jul 26 '16 at 11:48