Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between internal and no linkage

Tags:

c++

c

scope

linkage

Please refer to the following code that is in the same translation unit:

static int global_var; // file scope in C and global namespace scope in C++
                       // internal linkage
void f(void)
{
    static int local_var; // block scope in C and local scope in C++
                          // no linkage 
}

My understanding is this:

  • I can refer to global_var from anywhere in the translation unit because it has global scope.
  • I can refer to local_var only inside function f because it has local scope.

My questions:

  1. What is the difference beteen the two variables, in relation to linkage?
  2. Can you provide one example where internal and no linkage makes a difference, and the difference is derived not only from scope?

EDIT

After the answer and comments of James Kanze, I am now able to construct an example that shows the difference between the internal and no linkage attributes:

static int i; // definition
              // static storage
              // internal linkage

void f(void)
{
    extern int i; // declaration
                  // refers to the static i at file scope
                  // note that even though the specifier is extern
                  // its linkage is intern (this is legal in both C/C++)
    {
        int i; // definition
               // automatic storage
               // no linkage
    }
}


Some articles that do a good job at explaining the concepts involved:
- Scope regions in C and C++
- Storage class specifiers and storage duration
- Linkage in C and C++

like image 796
zephon Avatar asked Jul 21 '14 12:07

zephon


People also ask

What is the difference between internal 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 different types of linkages?

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

What is internal linkage in C?

Internal Linkage: An identifier implementing internal linkage is not accessible outside the translation unit it is declared in. Any identifier within the unit can access an identifier having internal linkage. It is implemented by the keyword static .

What is the difference between scope and linkage?

Linkage allows the correct association of each instance of an identifier with one particular object or function. Scope and linkage are distinguishable in that scope is for the benefit of the compiler, whereas linkage is for the benefit of the linker.


1 Answers

First: in addition to type, variables have three other characteristics: linkage, scope and lifetime. All four attributes are sort of orthogonal, but linked in the way they are expressed in the language, and do interact in some ways.

With regards to linkage: linkage really affects the symbol which is being declared, and not the object itself. If there is no linkage, all declarations of the symbol bind to different objects, e.g.:

int
func()
{
    int i;
    {
        int i;
    }
}

The symbol i has no linkage, and the two symbols i are bound to two different entities. Generally speaking, local variables (variables declared at block scope) and function arguments have no linkage, regardless of type and lifetime.

Internal and external linkage are similar, in that repeated declarations of the symbol bind to the same entity: internal linkage binds only within the translation unit, external accross the entire program. So given:

static int i;   //  internal linkage...

in several translation units, the i binds to a separate entity in each translation unit. Without the static, you have external linkage, and all of the i bind to the same entity.

Note that this only holds at namespace scope; all entities which are members of a non-local class have external linkage.

And that type has an impact: variables which are const implicitly have internal linkage:

int const i = 42;    //  same as static int const i...
extern int const j = 42;    //  external linkage.

Finally, all declarations which bind to the same entity must declare it to have the same type. If you violate this rule in a single translation unit (e.g.:

extern int i;
//   ...
double i;

in the same namespace scope), then the compiler should complain. If the two declarations are in different translation units, however, it is undefined behavior, and who knows what will happen. (In theory, the linker could complain, but most don't.)

EDIT:

One additional point: linkage is determined by the first declaration which can refer to the entity. So if I write:

static int i;

void
func()
{
    extern int i;
}

Both i refer to the same entity, which has internal linkage. (Why one would ever write the second declaration is beyond me, but it is legal.)

like image 99
James Kanze Avatar answered Sep 21 '22 18:09

James Kanze