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?
An anonymous namespace makes the enclosed variables, functions, classes, etc. available only inside that file. In your example it's a way to avoid global variables. There is no runtime or compile time performance difference.
External identifiers are the ones that are used in an external link process. These identifiers are also known as external names; include function names and global variable names that are shared between source files. The external identifier can be a name of the function or a global variable.
To use internal linkage we have to use which keyword? Explanation: static keyword is used for internal linkage.
Prerequisite : Namespaces in C++ An inline namespace is a namespace that uses the optional keyword inline in its original-namespace-definition. CPP.
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 atypedef
declaration in which the class has thetypedef
name for linkage purposes (7.1.3); or
— a named enumeration (7.2), or an unnamed enumeration defined in atypedef
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-
you can declare a non-const
variable, or a function, as extern
.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With