What is external linkage and internal linkage?
When you write an implementation file (
.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
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
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 18.104.22.168/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 22.214.171.124/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 126.96.36.199
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
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 188.8.131.52/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 184.108.40.206/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 220.127.116.11/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.
Checking the Neighbour Values of Arrays
Infinite Loop With Cin When Typing String While a Number Is Expected
Pass by Reference/Value in C++
Why Can't the Switch Statement Be Applied on Strings
Why Do I Get the Same Sequence For Every Run With Std::Random_Device With Mingw Gcc4.8.1
Where Are Static Variables Stored in C and C++
If You Shouldn't Throw Exceptions in a Destructor, How to Handle Errors in It
What Is External Linkage and Internal Linkage
Case-Insensitive String Comparison in C++
How to Print a Variable'S Type in Standard C++
Implicit Type Conversion Rules in C++ Operators
Overloading Friend Operator≪≪ For Template Class
C/C++ Maximum Stack Size of Program on Mainstream Oses
Running My C++ Code Gives Me a Blank Console
How to Call a Constructor from Another Constructor (Do Constructor Chaining) in C++
Print Heart Shape With Words Inside
When Should I Write the Keyword 'Inline' For a Function/Method