Why Do Functions/Objects Inside Anonymous Namespace Have External Linkage

Why do functions/objects inside anonymous namespace have external linkage?

In C++03, names with internal linkage were forbidden from being used as template arguments[*]. So, names of most things in unnamed namespaces had external linkage to allow their use with templates. You could explicitly give a name internal linkage in an unnamed namespace by declaring it static, same as in a named or global namespace.

Both things changed in C++11 -- names in unnamed namespaces have internal linkage by default (3.5/4), and names with internal linkage can be used as template arguments.

[*] for types, it must have external linkage. For objects and functions, it must have external linkage if its address is used as a template argument, although it's OK for example to use as a template argument the value of a const integer with internal linkage.

Example of entity declared in a anonymous namespace that has external linkage

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.

External linkage for name inside unnamed namespace

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.

Does declaring functions in anonymous namespace with static reduces the linking time and memory by not polluting the symbol table

1 - Is using a function with static keyword in the anonymous namespace helps with memory/linking time?

Static does not affect functions in anonymous namespace as far as the language is concerned. This is because being in an anonymous namespace already achieves the same thing as declaring the function static achieves. (Note that declaring a member function static has an entirely different meaning).

2 - Is there a way to check the symbol table in compiler explorer?

I don't know of compiler explorer, but you can use for example the nm program to list symbols: http://coliru.stacked-crooked.com/a/0281bc487044ec02

namespace {

void foo1(){} // internal linkage
static void foo2(){} // internal linkage

}

void foo3(){} // external linkage
static void foo4(){} // internal linkage

command:

nm main.o | c++filt

output:

0000000000000000 T foo3()

Why are unnamed namespaces used and what are their benefits?

Unnamed namespaces are a utility to make an identifier translation unit local. They behave as if you would choose a unique name per translation unit for a namespace:

namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }

The extra step using the empty body is important, so you can already refer within the namespace body to identifiers like ::name that are defined in that namespace, since the using directive already took place.

This means you can have free functions called (for example) help that can exist in multiple translation units, and they won't clash at link time. The effect is almost identical to using the static keyword used in C which you can put in in the declaration of identifiers. Unnamed namespaces are a superior alternative, being able to even make a type translation unit local.

namespace { int a1; }
static int a2;

Both a's are translation unit local and won't clash at link time. But the difference is that the a1 in the anonymous namespace gets a unique name.

Read the excellent article at comeau-computing Why is an unnamed namespace used instead of static? (Archive.org mirror).

Are objects in anonymous namespace implicitly static?

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

So in C++11 both of your foo objects have internal linkage. In C++03, the first one has external linkage.

Regardless of linkage, it has static storage duration.

I don't think there's any such thing in the standard as "take the object as if it was marked static", so I can't answer to that. If you find some text in the standard that refers to whether the object is "marked static" and doesn't refer specifically to either linkage or storage duration, then cite it and I can give you an opinion :-)

What does putting a structure in an anonymous namespace do?

Everything that's declared inside an anonymous namespace gets a unique, unknowable name, and thus cannot be referred to from any other translation unit. The anonymous namespace is thus guaranteed to be local to the current translation unit only, and never to clash with a different one.

For example, if you say namespace { int i; }, you are guaranteed that only the current translation unit sees the global i. Even if this declaration is in a header that's included in multiple, different TUs, each TU receives its own copy of the global variable (each with a different, unknowable fully-qualified name).

The effect was similar to declaring a global object static (which gives the global object internal linkage) in C++03, where objects in the anonymous namespace may still have external linkage. In C++11, names in an unnamed namespace have internal linkage as per 3.5/4, so the effect is exactly the same for variables and functions as declaring them static – but internal linkage applies to more than just variables and functions (e.g. enums, classes, templates), so as of C++11, you should always prefer unnamed namespaces!

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



Related Topics



Leave a reply



Submit