Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 766
user6898756 Avatar asked Sep 29 '16 10:09

user6898756


People also ask

What is internal linkage and external linkage?

Internal linkage refers to everything only in scope of a translation unit. External linkage refers to things that exist beyond a particular translation unit. In other words, accessible through the whole program, which is the combination of all translation units (or object files).

What are the types of linkages internal and external external internal and none external and none internal?

Explanation: External Linkage-> means global, non-static variables and functions. Internal Linkage-> means static variables and functions with file scope. None Linkage-> means Local variables.

What is a no linkage?

adjective Referring to an inheritance pattern for 2 genes on the same chromosome in which the frequency for crossing over is the same as it is for 2 genes on different chromosomes.

What are different types of linkages?

The two different types of linkage are: Complete linkage. Incomplete linkage.


2 Answers

§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.

like image 76
P.P Avatar answered Oct 07 '22 01:10

P.P


The compiler is giving this error because inside the a_External scope, a_Internal is still accessible, thus you are redeclaring a_Internal from static to extern in a_External because of the name collision of a. This problem can be solved by using different variable names, for example:

static int a1; //a_Internal

int main(void) {
    int a2; //a_Local
    {
        extern int a3; //a_External
    }
    return 0;
}
like image 38
tversteeg Avatar answered Oct 07 '22 01:10

tversteeg