I have 2 files A.cpp and B.cpp which look something like
A.cpp
----------
class w
{
public:
w();
};
B.cpp
-----------
class w
{
public:
w();
};
Now I read somewhere (https://en.cppreference.com/w/cpp/language/static) that classes have external linkage. So while building I was expecting a multiple definition error but on the contrary it worked like charm. However when I defined class w in A.cpp, I got the redefinition error which makes me believe that classes have internal linkage.
Am I missing something here?
The correct answer is yes, the name of a class may have external linkage. The previous answers are wrong and misleading. The code you show is legal and common.
The name of a class in C++03 can either have external linkage or no linkage. In C++11 the name of a class may additionally have internal linkage.
C++03
§3.5 [basic.link]
A name is said to have linkage when it might denote the same object,
reference, function, type, template, namespace or value as a name
introduced by a declaration in another scope
Class names can have external linkage.
A name having namespace scope has external linkage if it is the name
of
[...]
— a named class (clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage
purposes (7.1.3)
Class names can have no linkage.
Names not covered by these rules have no linkage. Moreover, except as
noted, a name declared in a local scope (3.3.2) has no linkage. A name
with no linkage (notably, the name of a class or enumeration declared
in a local scope (3.3.2)) shall not be used to declare an entity with
linkage.
In C++11 the first quote changes and class names at namespace scope may now have external or internal linkage.
An unnamed namespace or a namespace declared directly or indirectly
within an unnamed namespace has internal linkage. All other namespaces
have external linkage. A name having namespace scope that has not been
given internal linkage above [class names were not] has the same linkage
as the enclosing namespace if it is the name of
[...]
— a named class (Clause 9), or an unnamed class defined in a typedef
declaration in which the class has the typedef name for linkage
purposes (7.1.3);
The second quote also changes but the conclusion is the same, class names may have no linkage.
Names not covered by these rules have no linkage. Moreover, except as
noted, a name declared at block scope (3.3.3) has no linkage. A type
is said to have linkage if and only if:
— it is a class or enumeration type that is named (or has a name for
linkage purposes (7.1.3)) and the name has linkage; or
— it is an unnamed class or enumeration member of a class with linkage;
Some of the answers here conflate the abstract notion of linkage in the C++ Standard with the computer program known as a linker. The C++ Standard does not give special meaning to the word symbol. A symbol is what a linker resolves when combining object files into an executable. Formally, this is irrelevant to the notion of linkage in the C++ Standard. The document only ever addresses linkers in a footnote regarding character encoding.
Finally, your example is legal C++ and is not an ODR violation. Consider the following.
C.h
----------
class w
{
public:
w();
};
A.cpp
-----------
#include "C.h"
B.cpp
-----------
#include "C.h"
Perhaps this looks familiar. After preprocessor directives are evaluated we are left with the original example. The Wikipedia link provided by Alok Save even states this as an exception.
Some things, like types, templates, and extern inline functions, can
be defined in more than one translation unit. For a given entity, each
definition must be the same.
The ODR rule takes content into consideration. What you show is in fact required in order for a translation unit to use a class as a complete type.
§3.5 [basic.def.odr]
Exactly one definition of a class is required in a translation unit if
the class is used in a way that requires the class type to be
complete.
edit - The second half of James Kanze's answer got this right.
Technically, as Maxim points out, linkage applies to symbols, not to the
entities they denote. But the linkage of a symbol is partially
determined by what it denotes: symbols which name classes defined at
namespace scope have external linkage, and w denotes the same entity
in both A.cpp and B.cpp.
C++ has two different sets of rules concerning the definition of
entities: some entities, like functions or variables, may only be
defined once in the entire program. Defining them more than once will
result in undefined behavior; most implementations will (most of the
time, anyway) give a multiple definition error, but this is not required
or guaranteed. Other entities, such as classes or templates, are
required to be defined in each translation unit which uses them, with
the further requirement that every definition be identical: same
sequence of tokens, and all symbols binding to the same entity, with a
very limited exception for symbols in constant expressions, provided the
address is never taken. Violating these requirements is also undefined
behavior, but in this case, most systems will not even warn.
The class declaration
class w
{
public:
w();
};
does not produce any code or symbols, so there is nothing that could be linked and have "linkage". However, when your constructor w() is defined ...
w::w()
{
// object initialization goes here
}
it will have external linkage. If you define it in both A.cpp and B.cpp, there will be a name collision; what happens then depends on your linker. MSVC linkers e.g. will terminate with an error LNK2005 "function already defined" and/or LNK1169 "one or more multiply defined symbols found". The GNU g++ linker will behave similar. (For duplicate template methods, they will instead eliminate all but one instance; GCC docs call this the "Borland model").
There are four ways to resolve this problem:
If both classes are identical, put the definitions only into one .cpp file.
If you need two different, externally linked implementations of class w, put them into different namespaces.
Avoid external linkage by putting the definitions into an anonymous namespace.
namespace
{
w::w()
{
// object initialization goes here
}
}
Everying in an anonymous namespace has internal linkage, so you may also use it as a replacement for static declarations (which are not possible for class methods).
Avoid creating symbols by defining the methods inline:
inline w::w()
{
// object initialization goes here
}
No 4 will only work if your class has no static fields (class variables), and it will duplicate the code of the inline methods for each function call.
External linkage means the symbol (function or global variable) is accessible throughout your program and Internal linkage means that it's only accessible in one translation unit. you explicitly control the linkage of a symbol by using the extern and static keywords and the default linkage is extern for non-const symbols and static (internal) for const symbols.
A name with external linkage denotes an entity that can be referenced via names declared in the same scope or in other scopes of the same translation unit (just as with internal linkage), or additionally in other translation units.
The program actually violates the One Definition Rule but it is hard for the compiler to detect the error, because they are in different compilation units. And even the linker seems cannot detect it as an error.
C++ allows a workaround to bypass the One Definition Rule by making use of namespace.
[UPDATE] From C++03 Standard
§ 3.2 One definition rule, section 5 states:
There can be more than one definition of a class type ... in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then each definition of D shall consist of the same sequence of tokens.
Classes have no linkage to be pedantic.
Linkage only applies to symbols, that is, functions and variables, or code and data.
Seeing as you can't use static on a class, the only way to give a 'class' static linkage is to define the type in an anonymous namespace. Otherwise, it will have extern linkage. I put class in quotation marks because a class, which is a type, does not have a linkage, instead it is referring to the linkage of the symbols defined in the class scope (but not the linkage of an object made using the class). This includes static members and methods and non-static methods, but not non-static members as they are only part of the class type definition and do not additionally declare / define actual symbols.
The 'class' having static linkage means that the members and methods that would have had external linkage or external comdat linkage now both have static linkage only -- they are now local symbols, although the effect of inline at the compiler level still applies (i.e. it does not emit a symbol if it is not referenced in the translation unit) -- it's just no longer an external comdat symbol at assembler level, it's a local symbol. This is the case even if the member or method of the class is defined out-of-line and out of an anonymous namespace, it will still have static linkage.
If you declare the class type in an anonymous namespace, you will not be able to define the type outside of an anonymous namespace and it will not compile. You need to define it in the same anonymous namespace or a different anonymous namespace in the translation unit (different anonymous namespace doesn't matter because they're all combined into the same anonymous anonymous namespace name _GLOBAL__N_1).
This is the only way to change the linkage of members or methods of a class / struct because static will make it a static member and does not change the linkage, static will be ignored on out of line definitions, and extern is not allowed on class members / functions.
Related
According to the clause 3.5/4 of C++ Standard:
An unnamed namespace or a namespace declared directly or indirectly
within an unnamed namespace has internal linkage.
Simultanously in paragraph 7.3.1.1 we have note 96):
Although entities in an unnamed namespace might have external linkage,
they are effectively qualified by a name unique to their translation
unit and therefore can never be seen from any other translation unit.
How to explicitly make external linkage for name inside unnamed namespace and how to check that linkage is actually external if Standard guaranteed that there is no way to access name defined inside unnamed namespace from another translation unit?
In which cases doing explicit external linkage for name inside unnamed namespace is useful?
Re
” In which cases doing explicit external linkage for name inside unnamed namespace is useful?
The need for external linkage was important for C++03 templates. E.g. a function pointer as template argument had to be a pointer to function of external linkage. For example, the following would not compile with a C++03 compiler:
template< void(*f)() >
void tfunc() { f(); }
#include <stdio.h>
static void g() { printf( "Hello!\n" ); }
int main()
{
tfunc<g>();
}
It compiles fine with a C++11 compiler.
So, with C++11 the anonymous namespace mechanism for having external linkage yet no name conflicts between translation units, is only technically necessary for classes. A class has external linkage. One wouldn't want to have to choose class names that guaranteed did not occur in other translation units.
With C++11 the rules changed not only for template parameters, but for whether things in an anonymous namespace have external linkage or not. With C++03 an anonymous namespace had formally external linkage, possibly unless it is itself within an anonymous namespace (C++03 §3.5/4 last dash + C++03 §7.3.1.1/1). With C++11 an anonymous namespace has formally internal linkage.
This does not matter to the linker, because there's no linking of namespaces, but it matters as a formal device to describe linkage of things:
C++11 §3.5/4:
” An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
— a variable; or
— a function; or
— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or
— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or
— an enumerator belonging to an enumeration with linkage; or
— a template.
Before going on to your other questions, it's worth noting that this quote from the standard,
” Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit.
is plain wrong, because an extern "C" entity is visible from other translation units regardless of what namespace it's declared in.
Happily, as I recall, notes are non-normative, i.e. they do not define the language.
Re
” How to explicitly make external linkage for name inside unnamed namespace
just declare a non-const variable, or a function, as extern.
you can declare a non-const variable, or a function, as extern "C", making the linkage extern but at the same time making the namespaces irrelevant as far as linking is concerned: the C language doesn't have them.
namespace {
extern "C" void foo() {} // Extern linkage
} // namespace <anon>
void bar() {} // Also extern linkage, but visible to other TUs.
Re
” how to check that linkage is actually external
well, the linkage affects things like possible conflicts with the One Definition Rule, often abbreviated as the “ODR”, which in C++11 is §3.2.
So, one way to see the linkage in action is to link two object files generated from the above source, as if you had two translation units with that same source code:
C:\my\forums\so\088> g++ -c anon.cpp -o x.o & g++ -c anon.cpp -o y.o
C:\my\forums\so\088> g++ main.cpp x.o y.o
y.o:anon.cpp:(.text+0x0): multiple definition of `foo'
x.o:anon.cpp:(.text+0x0): first defined here
y.o:anon.cpp:(.text+0x7): multiple definition of `bar()'
x.o:anon.cpp:(.text+0x7): first defined here
collect2.exe: error: ld returned 1 exit status
C:\my\forums\so\088> _
The linker complains about multiple definitions of foo, because as with C language binding it appears, as far as the linker is concerned, as a non-inline external linkage member of the global namespace, with two (possibly conflicting) definitions.
How to explicitly make external linkage for name inside unnamed namespace
The only way I can think of is to give it C language linkage, so that its linkage name ignores the namespace qualification:
namespace {
extern void f() { } // has internal linkage despite 'extern'
extern "C" void g() { } // ignores linkage of namespace
}
void (*p)() = f; // ensure 'f' won't be optimized away
(A strict reading of the standard suggests that g should have internal linkage, but that's not what compilers seem to do.)
and how to check that linkage is actually external if Standard guaranteed that there is no way to access name defined inside unnamed namespace from another translation unit?
Typically ELF compilers will implement internal linkage with non-global symbols, so you can compile the code and inspect the object file:
$ g++ -c linkage.cc
$ nm linkage.o
0000000000000000 t _ZN12_GLOBAL__N_11fEv
0000000000000007 T g
0000000000000000 D p
The mangled name of the unnamed namespace can vary between compilers, but demangling it will show:
$ nm -C linkage.o
0000000000000008 t (anonymous namespace)::f()
0000000000000000 T g
0000000000000000 D p
The lowercase t shows that f has local visibility, meaning it can't be linked to from other object files. The uppercase T shows that g has external linkage.
This isn't guaranteed by the standard though, as ELF visibility is not part of the C++ standard, and some compilers implement linkage without using visibility even on ELF platforms, e.g. the EDG compiler produces a global symbol for the same code:
$ nm linkage.o
0000000000000008 T _ZN23_GLOBAL__N__7_link_cc_p1fEv
0000000000000004 C __EDGCPFE__4_9
0000000000000000 T g
0000000000000000 D p
$ nm -C linkage.o
0000000000000008 T (anonymous namespace)::f()
0000000000000004 C __EDGCPFE__4_9
0000000000000000 T g
0000000000000000 D p
So using extern "C" allows you to give a name external linkage even if it appears in an unnamed namespace, but that doesn't make the note correct, because you can refer to that name from other translation units, because it doesn't use the unnamed namespace scope. That suggests to me that the note is simply a leftover from C++03 when entities in unnamed namespaces didn't automatically have internal linkage, and the note should be corrected or removed (and indeed T.C. points out it was already removed by DR 1603).
In which cases doing explicit external linkage for name inside unnamed namespace is useful?
I can't think of any cases where it's useful.
According to the standard[3.5/2]:
When a name has external linkage , the entity it denotes can be
referred to by names from scopes of other translation units or from
other scopes of the same translation unit
and
When a name has internal linkage , the entity it denotes can be
referred to by names from other scopes in the same translation unit.
So basically if you can refer to something in a translation unit different from the one where this something has been defined then it has external linkage, otherwise it has internal linkage. So given the note from the question:
Although entities in an unnamed namespace might have external linkage,
they are effectively qualified by a name unique to their translation
unit and therefore can never be seen from any other translation unit.
We practically have a situation in which we have a name but we don't know it, hence no matter how hard we try we can't refer to it from the different translation unit. And it makes it indistinguishable from the one with internal linkage. So, in my opinion it is just a word juggling — if you can't distinguish one situation from another then they are the same.
The standard seems to imply that there is no restriction on the number of definitions of a variable if it is not odr-used (§3.2/3):
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
It does say that any variable can't be defined multiple times within a translation unit (§3.2/1):
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.
But I can't find a restriction for non-odr-used variables across the entire program. So why can't I compile something like the following:
// other.cpp
int x;
// main.cpp
int x;
int main() {}
Compiling and linking these files with g++ 4.6.3, I get a linker error for multiple definition of 'x'. To be honest, I expect this, but since x is not odr-used anywhere (as far as I can tell), I can't see how the standard restricts this. Or is it undefined behaviour?
Your program violates the linkage rules. C++11 §3.5[basic.link]/9 states:
Two names that are the same and that are declared in different scopes shall denote the same
variable, function, type, enumerator, template or namespace if
both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
when both names denote functions, the parameter-type-lists of the functions are identical; and
when both names denote function templates, the signatures are the same.
(I've cited the complete paragraph, for reference. The second two bullets do not apply here.)
In your program, there are two names x, which are the same. They are declared in different scopes (in this case, they are declared in different translation units). Both names have external linkage and both names refer to members of the same namespace (the global namespace).
These two names do not denote the same variable. The declaration int x; defines a variable. Because there are two such definitions in the program, there are two variables in the program. The name "x" in one translation unit denotes one of these variables; the name "x" in the other translation unit denotes the other. Therefore, the program is ill-formed.
You're correct that the standard is at fault in this regard. I have a feeling that this case falls into the gap between 3.2p1 (at most one definition per translation unit, as in your question) and 3.2p6 (which describes how classes, enumerations, inline functions, and various templates can have duplicate definitions across translation units).
For comparison, in C, 6.9p5 requires that (my emphasis):
An external definition is an external declaration that is also a definition of a function
(other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.
If standard does not say anything about definitions of unused variables then you can not imply that there may be multiple:
Undefined behavior may also be expected when this International
Standard omits the description of any explicit definition of
behavior.
So it may compile and run nicely or may stop during translation with error message or may crash runtime etc.
EDIT: See James McNellis answer the standard indeed actually has rules about it.
There is no error in compiling that, the error is in its linkage. By default your global variable or functions are public to other files(have extern storage) so at the end when linker want to link your code it see two definition for x and it can't select one of them, so if you do not use x of main.cpp in other.cpp and vice-verse make them static(that means only visible to the file that contain it)
// other.cpp
static int x;
// main.cpp
static int x;
I am working with a library. The library has one file containing the interface that I actually want exposed to other programs, contained in foo.h and foo.cpp. It also contains a bunch of helper classes and utility functions, in files bar1.h, bar2.h, bar1.cpp, bar2.cpp, etc.
If I compile all of these files and stick them in a .lib, the problem I run into is that some of the symbols in the bar files have very common names that clash with those in other external libraries I need to link against.
If all of the code were in one single .cpp file, I know how to fix this: I can use static or namespace { } to stop the linker from exporting the internal symbols. But obviously I have to declare the stuff in bar extern if I want to access it in foo.
I can wrap all of the .cpp files in namespace baz { }. If I choose baz carefully, so that there is little chance of it conflicting with namespaces used in other libraries, that will substantially fix the problem. But ideally, nothing outside of the symbols in foo.h should get exported into my .lib. Is there a technique for doing this?
You can achieve this, however it comes at some cost:
in C++ you can have internal linkage. Anything inside a unnamed namespace has internal linkage* (see footnote), as well as static free functions (you should prefer the anonymous namespace).
Update: here's the C++11 standard quote from §3.5,4:
An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
— a variable; or
— a function; or
— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or
— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or
— an enumerator belonging to an enumeration with linkage; or
— a template.
However, internal linkage applies to translation units, not to static libraries. So if you would use the usual approach putting each class in its own translation unit (=cpp), you could not define them inside anonymous namespaces because you could not link them together to build the library.
You can solve this dilemma by making the whole library one single translation unit: one header providing the library's public interface, one source with the function definitions, and anything else as headers, defined in anonymous namespaces:
mylib.hpp
class MyLib {
public:
int foo();
double bar(int i);
};
mylib.cpp
#include "mylib.hpp"
#include "mylibimpl.h"
int MyLib::foo() {
return fooimpl();
}
double MyLib::bar(int i) {
return BarImpl(i).do();
}
mylibimpl.h
namespace {
inline int fooimpl() { return 42; }
class BarImpl {
double d;
public:
BarImpl(int i) : d(i*3.42) {}
double do() { return 2*d; }
};
}
You'll now have one translation unit (mylib.o / mylib.lib), and all the *impl classes and functions cannot be seen from outside, because they have internal linkage.
The cost is that you have to reorganize the sources of your internal classes (e.g. to resolve circular dependencies) and that every simple change of the library's internal code will lead to one big recompilation of everything in the lib, just because there is only the single huge translation unit. So you should do this only when the library code itself is very stable or if the library is not too big.
The benefit besides the complete hiding of internal symbols is that the compiler will be able to pull out any optimization it wants, because no implementation details are hidden in different translation units.
*Footnote:
As was commented by Billy ONeal, in C++03 entities in anonymous namespaces have not necessarily internal linkage. However, if they have external linkage, they have names unique to their tranlsation unit and are effectively not accessible from outside that TU, meaning that this procedure works in C++03 as well.
Why the following doesn't compile?
...
extern int i;
static int i;
...
but if you reverse the order, it compiles fine.
...
static int i;
extern int i;
...
What is going on here?
This is specifically given as an example in the C++ standard when it's discussing the intricacies of declaring external or internal linkage. It's in section 7.1.1.7, which has this exert:
static int b ; // b has internal linkage
extern int b ; // b still has internal linkage
extern int d ; // d has external linkage
static int d ; // error: inconsistent linkage
Section 3.5.6 discusses how extern should behave in this case.
What's happening is this: static int i (in this case) is a definition, where the static indicates that i has internal linkage. When extern occurs after the static the compiler sees that the symbol already exists and accepts that it already has internal linkage and carries on. Which is why your second example compiles.
The extern on the other hand is a declaration, it implicitly states that the symbol has external linkage but doesn't actually create anything. Since there's no i in your first example the compiler registers i as having external linkage but when it gets to your static it finds the incompatible statement that it has internal linkage and gives an error.
In other words it's because declarations are 'softer' than definitions. For example, you could declare the same thing multiple times without error, but you can only define it once.
Whether this is the same in C, I do not know (but netcoder's answer below informs us that the C standard contains the same requirement).
For C, quoting the standard, in C11 6.2.2: Linkage of identifiers:
3) If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.
4) For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the
linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
(emphasis-mine)
That explains the second example (i will have internal linkage). As for the first one, I'm pretty sure it's undefined behavior:
7) If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
...because extern appears before the identifier is declared with internal linkage, 6.2.2/4 does not apply. As such, i has both internal and external linkage, so it's UB.
If the compiler issues a diagnostic, well lucky you I guess. It could compile both without errors and still be compliant to the standard.
C++:
7.1.1 Storage class specifiers [dcl.stc]
7) A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has
internal linkage because of a previous declaration and provided it is not declared const. Objects declared
const and not explicitly declared extern have internal linkage.
So, the first one attempts to first gives i external linkage, and internal afterwards.
The second one gives it internal linkage first, and the second line doesn't attempt to give it external linkage because it was previously declared as internal.
8) The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope,
each declaration declaring the same variable name or the same overloading of a function name shall imply
the same linkage. Each function in a given set of overloaded functions can have a different linkage, however.
[ Example:
[...]
static int b; // b has internal linkage
extern int b; // b still has internal linkage
[...]
extern int d; // d has external linkage
static int d; // error: inconsistent linkage
[...]
In Microsoft Visual Studio, both versions compile just fine.
On Gnu C++ you get an error.
I'm not sure which compiler is "correct". Either way, having both lines doesn't make much sense.
extern int i means that the integer i is defined in some other module (object file or library). This is a declaration. The compiler will not allocate storage the i in this object, but it will recognize the variable when you are using it somewhere else in the program.
int i tells the compiler to allocate storage for i. This is a definition. If other C++ (or C) files have int i, the linker will complain, that int i is defined twice.
static int i is similar to the above, with the extra functionality that i is local. It cannot be accessed from other module, even if they declare extern int i. People are using the keyword static (in this context) to keep i localize.
Hence having i both declared as being defined somewhere else, AND defined as static within the module seems like an error. Visual Studio is silent about it, and g++ is silent only in a specific order, but either way you just shouldn't have both lines in the same source code.
I want to understand the external linkage and internal linkage and their difference.
I also want to know the meaning of
const variables internally link by default unless otherwise declared as extern.
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).
As dudewat said external linkage means the symbol (function or global variable) is accessible throughout your program and internal linkage means that it is only accessible in one translation unit.
You can explicitly control the linkage of a symbol by using the extern and static keywords. If the linkage is not specified then the default linkage is extern (external linkage) for non-const symbols and static (internal linkage) for const symbols.
// In namespace scope or global scope.
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// The same goes for functions (but there are no const functions).
int f(); // extern by default
static int sf(); // explicitly static
Note that instead of using static (internal linkage), it is better to use anonymous namespaces into which you can also put classes. Though they allow extern linkage, anonymous namespaces are unreachable from other translation units, making linkage effectively static.
namespace {
int i; // extern by default but unreachable from other translation units
class C; // extern by default but unreachable from other translation units
}
A global variable has external linkage by default. Its scope can be extended to files other than containing it by giving a matching extern declaration in the other file.
The scope of a global variable can be restricted to the file containing its declaration by prefixing the declaration with the keyword static. Such variables are said to have internal linkage.
Consider following example:
1.cpp
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
The signature of function f declares f as a function with external linkage (default). Its definition must be provided later in this file or in other translation unit (given below).
max is defined as an integer constant. The default linkage for constants is internal. Its linkage is changed to external with the keyword extern. So now max can be accessed in other files.
n is defined as an integer variable. The default linkage for variables defined outside function bodies is external.
2.cpp
#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
max is declared to have external linkage. A matching definition for max (with external linkage) must appear in some file. (As in 1.cpp)
n is declared to have external linkage.
z is defined as a global variable with internal linkage.
The definition of nCall specifies nCall to be a variable that retains its value across calls to function f(). Unlike local variables with the default auto storage class, nCall will be initialized only once at the first invocation of f(). The storage class specifier static affects the lifetime of the local variable and not its scope.
NB: The keyword static plays a double role. When used in the definitions of global variables, it specifies internal linkage. When used in the definitions of the local variables, it specifies that the lifetime of the variable is going to be the duration of the program instead of being the duration of the function.
In terms of 'C' (Because static keyword has different meaning between 'C' & 'C++')
Lets talk about different scope in 'C'
SCOPE: It is basically how long can I see something and how far.
Local variable : Scope is only inside a function. It resides in the STACK area of RAM.
Which means that every time a function gets called all the variables
that are the part of that function, including function arguments are
freshly created and are destroyed once the control goes out of the
function. (Because the stack is flushed every time function returns)
Static variable: Scope of this is for a file. It is accessible every where in the file
in which it is declared. It resides in the DATA segment of RAM. Since
this can only be accessed inside a file and hence INTERNAL linkage. Any
other files cannot see this variable. In fact STATIC keyword is the
only way in which we can introduce some level of data or function
hiding in 'C'
Global variable: Scope of this is for an entire application. It is accessible form every
where of the application. Global variables also resides in DATA segment
Since it can be accessed every where in the application and hence
EXTERNAL Linkage
By default all functions are global. In case, if you need to
hide some functions in a file from outside, you can prefix the static
keyword to the function. :-)
Before talking about the question, it is better to know the term translation unit, program and some basic concepts of C++ (actually linkage is one of them in general) precisely. You will also have to know what is a scope.
I will emphasize some key points, esp. those missing in previous answers.
Linkage is a property of a name, which is introduced by a declaration. Different names can denote same entity (typically, an object or a function). So talking about linkage of an entity is usually nonsense, unless you are sure that the entity will only be referred by the unique name from some specific declarations (usually one declaration, though).
Note an object is an entity, but a variable is not. While talking about the linkage of a variable, actually the name of the denoted entity (which is introduced by a specific declaration) is concerned. The linkage of the name is in one of the three: no linkage, internal linkage or external linkage.
Different translation units can share the same declaration by header/source file (yes, it is the standard's wording) inclusion. So you may refer the same name in different translation units. If the name declared has external linkage, the identity of the entity referred by the name is also shared. If the name declared has internal linkage, the same name in different translation units denotes different entities, but you can refer the entity in different scopes of the same translation unit. If the name has no linkage, you simply cannot refer the entity from other scopes.
(Oops... I found what I have typed was somewhat just repeating the standard wording ...)
There are also some other confusing points which are not covered by the language specification.
Visibility (of a name). It is also a property of declared name, but with a meaning different to linkage.
Visibility (of a side effect). This is not related to this topic.
Visibility (of a symbol). This notion can be used by actual implementations. In such implementations, a symbol with specific visibility in object (binary) code is usually the target mapped from the entity definition whose names having the same specific linkage in the source (C++) code. However, it is usually not guaranteed one-to-one. For example, a symbol in a dynamic library image can be specified only shared in that image internally from source code (involved with some extensions, typically, __attribute__ or __declspec) or compiler options, and the image is not the whole program or the object file translated from a translation unit, thus no standard concept can describe it accurately. Since symbol is not a normative term in C++, it is only an implementation detail, even though the related extensions of dialects may have been widely adopted.
Accessibility. In C++, this is usually about property of class members or base classes, which is again a different concept unrelated to the topic.
Global. In C++, "global" refers something of global namespace or global namespace scope. The latter is roughly equivalent to file scope in the C language. Both in C and C++, the linkage has nothing to do with scope, although scope (like linkage) is also tightly concerned with an identifier (in C) or a name (in C++) introduced by some declaration.
The linkage rule of namespace scope const variable is something special (and particularly different to the const object declared in file scope in C language which also has the concept of linkage of identifiers). Since ODR is enforced by C++, it is important to keep no more than one definition of the same variable or function occurred in the whole program except for inline functions. If there is no such special rule of const, a simplest declaration of const variable with initializers (e.g. = xxx) in a header or a source file (often a "header file") included by multiple translation units (or included by one translation unit more than once, though rarely) in a program will violate ODR, which makes to use const variable as replacement of some object-like macros impossible.
I think Internal and External Linkage in C++ gives a clear and concise explanation:
A translation unit refers to an implementation (.c/.cpp) file and all
header (.h/.hpp) files it includes. If an object or function inside
such a translation unit has internal linkage, then that specific
symbol is only visible to the linker within that translation unit. If
an object or function has external linkage, the linker can also see it
when processing other translation units. The static keyword, when used
in the global namespace, forces a symbol to have internal linkage. The
extern keyword results in a symbol having external linkage.
The compiler defaults the linkage of symbols such that:
Non-const global variables have external linkage by default
Const global variables have internal linkage by default
Functions have external linkage by default
Basically
extern linkage variable is visible in all files
internal linkage variable is visible in single file.
Explain: const variables internally link by default unless otherwise declared as extern
by default, global variable is external linkage
but, const global variable is internal linkage
extra, extern const global variable is external linkage
A pretty good material about linkage in C++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
Linkage determines whether identifiers that have identical names refer to the same object, function, or other entity, even if those identifiers appear in different translation units. The linkage of an identifier depends on how it was declared.
There are three types of linkages:
Internal linkage : identifiers can only be seen within a translation unit.
External linkage : identifiers can be seen (and referred to) in other translation units.
No linkage : identifiers can only be seen in the scope in which they are defined.
Linkage does not affect scoping
C++ only : You can also have linkage between C++ and non-C++ code fragments, which is called language linkage.
Source :IBM Program Linkage
In C++
Any variable at file scope and that is not nested inside a class or function, is visible throughout all translation units in a program. This is called external linkage because at link time the name is visible to the linker everywhere, external to that translation unit.
Global variables and ordinary functions have external linkage.
Static object or function name at file scope is local to translation unit. That is
called as Internal Linkage
Linkage refers only to elements that have addresses at link/load time; thus, class declarations and local variables have no linkage.