What Is External Linkage and Internal Linkage

What is external linkage and internal linkage?

When you write an implementation file (.cpp, .cxx, etc) your compiler generates a translation unit. This is the source file from your implementation plus all the headers you #included in it.

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

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

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

Example of showing internal vs external linkage

You need to have declarations of both variables in scope.c.

Try adding extern int external, internal; in scope.c before the definition of main. This will fix the compiler errors you're undoubtedly seeing for both variables. But you will still get a linker error for internal only. If you comment out the line that prints internal, but leave the line that prints external alone, the program will compile, link and run.

How does external / internal identifier relate to the linkage?

C17 uses the term "external identifier" in these places (exhaustive list):

  • Paragraph 5.2.4.1/1 requiring that a conforming implementation be able to translate and execute at least one program containing at least 31 significant initial characters in an external identifier.

  • Footnote 72 to paragraph 6.4.2.1/3, discussing the semantics and handling of extended characters in identifiers on systems whose linkers cannot accept extended characters. On such systems, "Extended characters may produce a long external identifier."

  • Paragraph 7.16.1/1, about potential name collisions with the va_* variadic-argument access macros / functions.

  • Paragraph 7.17.1/6, about potential name collisions with the generic functions declared in stdatomic.h.

  • Paragraph J.1/1, referring back to section 5.2.4.1

  • Paragraph J.2/1, referring to undefined behavior described in section 7.13 in the event that "the program defines an external identifier with the name setjmp."

  • Paragraph J.2/1, referring to section 7.16

All of those are about linkage -- that is, the association of identifiers with the objects or functions -- not about (say) the lexical context of the identifier's declaration.

Furthermore, although the specification does not explicitly define "external identifier", it does, in paragraph 6.4.2.1/5, define "external name" as "identifier that has external linkage". It also uses the word "name" as a synonym for "identifier" in several places, generally in the context of function names.

I have every reason, then, to take "external identifier" to be synonymous with "external name" and "identifier with external linkage". The main alternative would seem to be "identifier declared in an external declaration", but it makes little sense that some of the particular provisions related to external identifiers should apply only to identifiers appearing in external declarations and not to identifiers declared at block scope with external linkage.


The term "internal identifier" appears only once in C17, in paragraph 5.2.4.1/1, requiring that a conforming implementation be able to translate and execute at least one program containing at least 63 significant initial characters in an internal identifier. This is parallel to one of the appearances of "external identifier", and, also parallel to "external identifier", there is a definition the related term "internal name": "a macro name or an identifier that does not have external linkage" (paragraph 6.4.2.1/5).

Similarly to the case with "external identifier", then, I take "internal identifier" to be synonymous with "internal name": an identifier that does not have external linkage. Another way to say that would be an identifier with internal linkage or no linkage.

inline definition of function - external or internal linkage

Your example actually violates the one definition rule. In short, with an inline function you're allowed to have multiple definitions provided that each one:

  • is in a different translation unit (which you do have)
  • each definition has the same sequence of tokens (which you clearly do not)

So this is actually UB.

inline functions require there to be a definition in every translation unit where they are ODR used, so they can be completely defined in a header without a compilation unit for example.

This is not the same as "inlining" a function. inline only implies that the function is defined "in-line" with it's declaration. Any function will or will not be inlined at the discretion of your compiler.

external vs internal linkage and performance

No, all three have external linkage. Member functions of a non-local class always have external linkage in C++. Moreover, inline has no effect on linkage, even if it is a non-member function.

Linkage has no effect on efficiency. Inlining might have, but it depends on too many variables.



Related Topics



Leave a reply



Submit