Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did they insist in using the `extern` specifier in the examples below?

[basic.link]/6 (my emphasiss):

The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. ...

static void f();
static int i = 0;

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

[basic.link]/7:
...

namespace X {
    void p() {
        q(); // error: q not yet declared
        extern void q(); // q is a member of namespace X  <--
    }
    void middle() {
        q(); // error: q not yet declared
    }
    void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q

The externspecifiers pointed by the arrows are not necessary, given the very first sentence in paragraph [basic.link]/6 highlighted in bold characters above.Or am I missing something?

like image 438
João Afonso Avatar asked Feb 21 '17 20:02

João Afonso


2 Answers

The externs are there to emphasize the respective comments, pointing out that the extern has no effect in certain circumstances (due to the rules outlined in that paragraph).

In the first example, f has internal linkage despite being declared extern, because it was first declared static at namespace-scope.

In the second exmaple, extern has no effect on the declaration because q is also declared at namespace scope without it (and X::q takes precedence over ::q).

like image 119
ildjarn Avatar answered Oct 05 '22 07:10

ildjarn


I think the examples stave off some plausible but wrong ideas one might otherwise come up with.

In paragraph 6 one might expect f() to have external linkage since that is what extern "normally" (i.e. at file scope) means, but it's actually internal linkage because of the static declaration further up.

In paragraph 7 someone might expect extern void q(); to make q() available outside of (or in loose speech external to) p(), so it could be called in middle(), but that doesn't happen either.

Both would still be true without the extern keyword, but then it wouldn't be surprising to people expecting extern to mean something different.

like image 21
Brendan E. Coughlan Avatar answered Oct 05 '22 08:10

Brendan E. Coughlan