Given the statements below (emphasis mine) in §3.5/4 and in the Note [94] in §7.3.1.1/1, I'd like to have one single example of an entity declared in a unnamed namespace that has external linkage.
§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.
Note [94] on §7.3.1.1/1:
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.
The term external linkage means that a symbol in one translation unit can be accessed from other translation units, whereas exporting refers to a symbol that is visible from a library file such as a DLL. Only external linkage symbols can be exported.
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.
Theoretically, extern variables declared in anonymous namespace is a superior alternative over a simple static variable. That's why the "static global variables" were deprecated before C++11.
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.
With C++11 an anonymous namespace has formally 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.
Thus, the declaration of an externally linked identifier does not take up any space. Extern identifiers are generally stored in initialized/uninitialized or text segment of RAM. Please do go through Understanding extern keyword in C before proceeding to the following examples. It is possible to use an extern variable in a local scope.
The keyword extern implements external linkage. When we use the keyword extern, we tell the linker to look for the definition elsewhere. Thus, the declaration of an externally linked identifier does not take up any space.
You are looking at a defect in the standard.
The change that makes unnamed namespace members have internal linkage happened fairly late in the C++11 standardization process, in November 2010 (CWG issue 1113). As a result, a number of places in the standard needs to be changed, but weren't. One of which is the footnote you quoted.
CWG issue 1603, currently in "ready" status (read: the resolution is likely to be adopted at the next committee meeting), will fix this and a number of other issues related to giving internal linkage to unnamed namespace members.
It's a good question because it's difficult to demonstrate. We can take advantage of other rules in the C++ Standard to show that a variable in an anonymous namespace can have external linkage.
Templating on an int* with external linkage will succeed while templating on an int* with internal linkage will fail.
#include <iostream>
namespace {
// not externally linked, won't compile
// const int i = 5;
// external linkage, compiles
extern int i;
int i = 5;
}
template<int* int_ptr>
struct temp_on_extern_linked_int {
temp_on_extern_linked_int() {
std::cout << *int_ptr << std::endl;
}
};
int main() {
temp_on_extern_linked_int<&i>();
}
As shown the program compiles and runs.
$ g++-4.8 main.cpp -o main
$ ./main
5
Uncommenting the other definition of i
causes the compile to fail.
$ g++-4.8 main.cpp -o main
main.cpp: In function 'int main()':
main.cpp:17:30: error: '& {anonymous}::i' is not a valid template argument of
type 'int*' because '{anonymous}::i' does not have external linkage
temp_on_extern_linked_int<&i>();
^
The compiler is quite helpful. It explicitly states that because i
doesn't have external linkage the compile failed.
The commented definition of i
has internal linkage because it is qualified const without extern. (§3.4.6)
Variables at namespace scope that are declared const and not extern have internal linkage.
Part of the trick is not compiling as C++11.
Why did C++03 require template parameters to have external linkage?
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