64

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    Not an actual paper trail, but from the duplicate of the linked question, there are [notes from the November 2010 standard committee meeting](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012) stating this feature will never be removed from the language. – André Caron Dec 10 '11 at 22:19
  • Related: http://stackoverflow.com/q/4726570/1468366 – MvG Dec 12 '15 at 01:07

3 Answers3

40

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.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 1
    +1 for the template specialization and the inline namespace explanation. – emsr Dec 11 '11 at 15:48
  • 1
    A template specialization depending on `static` would violate the ODR because resolution of each template-id (given a complete template argument list) is required to be independent of the point of instantiation, including points in different TUs. – Potatoswatter Feb 08 '14 at 12:16
  • 1
    What's this about specializing templates? Specializations don't have linkage independent of that of the primary template anyway. (They might in practice be implemented with local symbols if the implementation knows that they can't be named elsewhere because they involve other local symbols.) – Davis Herring Nov 29 '22 at 06:19
35

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.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    Can't you prevent that from happening with a `using ::a;` declaration? – Potatoswatter Dec 11 '11 at 09:19
  • 1
    i tried compiling that: unnam.cpp: In function 'int main()': unnam.cpp:11: error: reference to 'a' is ambiguous – Erik Aronesty Jan 15 '15 at 18:45
  • @ErikAronesty I doubt you tried exactly that, because my code has no `main` function, whereas your compiler complains about some code within a function called `main`. So if you use above code and wonder why it raises an error in a broader context (I'm pretty sure there is a conclusive explanation), please put up a new Stackoverflow question. – Johannes Schaub - litb Jan 16 '15 at 00:09
  • Scope has nothing to do with linkage. – user2394284 Mar 19 '16 at 09:42
  • 3
    @user2394284 I guess I'm unsure what your comment means or what it is supposed to clarify. The definition of linkage is such.. "A name is said to have /linkage/ when it might denote the same ... as a name introduced by a declaration in another scope". It seems a big stretch to assert that one has nothing to do with the other if one is even needed in the definition of the other. – Johannes Schaub - litb Mar 19 '16 at 14:04
  • While what you've said is correct, it seems to me that for all practical purposes you could use `inline` anonymous namespaces to achieve everything that a `static` declaration would. Though your example would compile, any attempt to use either of the `a` variables would cause an unavoidable ambiguity error. (This is not quite as true if the anonymous namespace is _not_ declared as `inline`, and I realise the question did not mention `inline` namespaces). – davmac Mar 10 '17 at 16:54
16

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.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
  • 2
    Thanks for the explanation and sharing your usual practice! I think it could be treated as the one of the "best practices". – Siu Ching Pong -Asuka Kenji- Jul 31 '14 at 12:48
  • 5
    I know that cppreference.com is not the standard, but I've not known them to be wrong, and at http://en.cppreference.com/w/cpp/language/namespace#Unnamed_namespaces they say unnamed namespaces have internal linkage. So: internal or external? – davidbak Sep 17 '14 at 02:57
  • 2
    How would the code execute faster? Don't you just mean it would link faster? – paulm Apr 27 '15 at 07:21
  • @paulm: no, I meant *execute*. E.g. names with internal linkage cannot be overridden by something like `LD_PRELOAD`, so the optimizer can make more assumptions. – Marc Mutz - mmutz Apr 29 '15 at 09:06
  • 1
    @davidbak: I believe this is new in C++11. – Marc Mutz - mmutz Apr 29 '15 at 09:07
  • 1
    Unless the symbol is exported how could that be? At least on windows this shouldn't change anything. If the function is exported then the compiler is still free to inline other copies of it in the same binary – paulm Apr 29 '15 at 10:21
  • @MarcMutz-mmutz Are the consequences of the use of `LD_PRELOAD` well defined? – curiousguy Aug 19 '15 at 18:48
  • 3
    This is a good answer except that the terminology is at odds with the standard. Specifically, the standard says names in an unnamed namespace have _internal_ linkage. The point I think you're trying to make is that names of `static` functions generally aren't even added to the symbol table needed by the linker. Functions in unnamed namespaces, however, generally are added to the symbol table but marked as internal or mangled so that they are effectively inaccessible. – Adrian McCarthy May 17 '16 at 16:59
  • 3
    In fact, names of functions in unnamed namespaces don't need to be added to the symbol table any differently than `static` functions; they both have internal linkage, and may both be handled in the same way (which they are, by at least GCC). I do not believe this answer is correct. – davmac Mar 10 '17 at 16:47
  • @AdrianMcCarthy I don't think that is true. At least nowadays, compilers do not anything to the symbol table if it is not needed, not even with unnamed namespaces. – Acorn May 09 '19 at 15:54
  • 1
    "names in unnamed namespaces (the standard's term for anonymous namespaces) have external linkage" this is just incorrect when compared with cppreference "any name that is declared within an unnamed namespace has internal linkage" – Xeverous Mar 26 '22 at 21:57