Why are anonymous namespaces not a sufficient replacement for namespace-static, according to the standards committee?

C++C++11

C++ Problem Overview


According to this answer, namespace-scoped static variables were undeprecated in C++11. That is, they were deprecated in C++03, because anonymous namespaces were considered better. But C++11 undeprecated them.

Why? N3296 lists the reasoning for this as:

> The use of static in namespace scope should not be deprecated. Anonymous namespaces are not a sufficient replacement for the functionality.

This was apparently accepted by the committee. Why? What is it about anonymous namespaces that does not completely replace this functionality?

I would prefer answers that had some documentation or paper trail of a standards committee discussion.

C++ Solutions


Solution 1 - C++

This is a more in-depth explanation.

>Although 7.3.1.1 [namespace.unnamed] states that the use of the static keyword for declaring variables in namespace scope is deprecated because the unnamed namespace provides a superior alternative, it is unlikely that the feature will be removed at any point in the foreseeable future, especially in light of C compatibility concerns. The Committee should consider removing the deprecation.

One issue I know is that anonymous namespaces can't specialize templates outside of the namespace block. This is why inline namespace was introduced, although static works too. Also, static plays much nice with macros.

Solution 2 - C++

With unnamed namespaces you cannot give a variable internal linkage within the same namespace you are currently in. With static, you can. For example, the following use of unnamed namespaces does not give a global variable internal linkage

namespace { int a; } 
int a; // oops, no error!

Had the first a been declared as static, the attempt to declare a second a at global scope would have been an error immediately because the first a already exists at global scope.

So to achieve their job of making identity unique, unnamed namespaces place entities into different namespaces (in addition to affecting their linkage). static only affects the linkage, leaving the namespace of which functions and variables are a member of unchanged.

Solution 3 - C++

The user-in-the-trenches answer would be that names in unnamed namespaces (the standard's term for anonymous namespaces) have external linkage and names declared static at namespace level have internal linkage.

Internal linkage has two advantages, only one of which unnamed namespaces provide, too:

  1. They make names local to the translation-unit. I can define the same function fun differently in different translation units without violating the One-Definition-Rule. This property is shared by names in the unnamed namespace, by adorning them with a unique namespace name.

  2. They prevent the name from entering into the global symbol table. This is strictly an optimisation, but an important one in practice. This property is not shared by names in the unnamed namespace.

So, in general, a program that uses static for its translation-unit-local namespace-level functions generates less work for the linker and might execute faster than the equivalent program using the unnamed namespace.

That said, you need to use the unnamed namespace for types that you want to pass as template arguments, because template arguments must have external linkage.

So I usually do the follwing: define free functions as static, but put types into the unnamed namespace.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNicol BolasView Question on Stackoverflow
Solution 1 - C++PubbyView Answer on Stackoverflow
Solution 2 - C++Johannes Schaub - litbView Answer on Stackoverflow
Solution 3 - C++Marc Mutz - mmutzView Answer on Stackoverflow