Search code examples
clanguage-lawyerlinkage

External, internal and no linkage or why this does not work?


According to C standard:

In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.

In my example we have three separate declarations with each identifier having a different linkage.So why doesn't this work?

static int a; //a_Internal

int main(void) {
    int a; //a_Local
    {
        extern int a; //a_External
    }
    return 0;
}

Error:

In function 'main': Line 9: error: variable previously declared 'static' redeclared 'extern'

Why does compiler insist that I'm redeclaring instead of trying to access external object in another file?

Valid C++ example for reference:

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

Both Clang and VC seem to be okay with my C example; only some versions of GCC (not all) produce the aforementioned error.


Solution

  • §6.2.2, 7 says:

    If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

    So, your program has undefined behaviour.

    §6.2.2, 4 says that

    extern int a; //a_External
    

    has external linkage because the prior declaration visible in the scope int a; //a_Local has no linkage. But

    static int a; //a_Internal
    

    declares a with internal linkage. Hence, it's undefined per §6.2.2, 7.