114

The section $7.3.1.1/2 from the C++ Standard reads:

The use of the static keyword is deprecated when declaring objects in a namespace scope; the unnamed-namespace provides a superior alternative.

I don't understand why an unnamed namespace is considered a superior alternative? What is the rationale? I've known for a long time as to what the standard says, but I've never seriously thought about it, even when I was replying to this question: Superiority of unnamed namespace over static?

Is it considered superior because it can be applied to user-defined types as well, as I described in my answer? Or is there some other reason as well, that I'm unaware of? I'm asking this, particularly because that is my reasoning in my answer, while the standard might have something else in mind.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I would like to know this too. I would guess it is only superior because of static is deprecated for function definitions. Also you have a way to define local classes with a unnamed namespace. – frast Feb 12 '11 at 09:08
  • 3
    I am very confused. You seem to provide a pretty good answer to the other question. What exactly was left unanswered in your mind? – Marcelo Cantos Feb 12 '11 at 09:08
  • @Marcelo Cantos: I edited my question. :-) – Nawaz Feb 12 '11 at 09:12
  • Or http://stackoverflow.com/questions/4422507/superiority-of-unnamed-namespace-over-static – James McNellis Feb 12 '11 at 09:12
  • @James : hehe... you're referring to the same topic as possible duplicate, which I'm already referring to, in my question. – Nawaz Feb 12 '11 at 09:18
  • I'm with @Marcelo here. It's already been answered in http://stackoverflow.com/questions/4422507/superiority-of-unnamed-namespace-over-static. Voting to close. – sbi Feb 12 '11 at 09:22
  • 4
    If anything, this question should stay and 4422507 should be closed, because here we see real reasons listed and not just a pointer to the standard. – Eli Bendersky Feb 14 '11 at 13:49
  • @Eli Bendersky: I completely agree. :-) – Nawaz Feb 14 '11 at 14:22
  • For what it's worth, [the committee ended up wondering this as well](http://stackoverflow.com/a/8460248/560648). :) – Lightness Races in Orbit Dec 10 '11 at 22:06
  • However, unnamed namespaces are not a sufficient replacement for _namespace-static_, according to the standards committee. [There still are a few instances](http://stackoverflow.com/q/8460327/183120) where unnamed namespaces fail and only `static` works. – legends2k Dec 06 '13 at 10:32
  • C++ standard 7.3.1.1/2 seems to be amended in 2010 and the sentence has been removed. But I think that while use of static keyword in this case is not anymore deprecated, anomymous namespace make the programmer intent clearer. – VGE Jun 17 '15 at 15:23

3 Answers3

126
  • As you've mentioned, namespace works for anything, not just for functions and objects.
  • As Greg has pointed out, static means too many things already.
  • Namespaces provide a uniform and consistent way of controlling visibility at the global scope. You don't have to use different tools for the same thing.
  • When using an anonymous namespace, the function/object name will get mangled properly, which allows you to see something like "(anonymous namespace)::xyz" in the symbol table after de-mangling, and not just "xyz" with static linkage.
  • As pointed out in the comments below, it isn't allowed to use static things as template arguments, while with anonymous namespaces it's fine.
  • More? Probably, but I can't think of anything else right now.
knittl
  • 246,190
  • 53
  • 318
  • 364
Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
  • 21
    +1. In addition, C++ does not allow types and pointers/referenes to objects or functions with internal linkage (static) to be used as template parameters. Replacing static with anonymous namespace still "hides" the things from other translation units but they keep external linkage (mostly) and can so be used as template arguments. But I'd say the main purpose of anonymous namespaces was probably to get rid of one of the overloaded meanings of static. – sellibitze Feb 12 '11 at 11:22
  • @sellibitze, very interesting, added that to the answer. Just one point to clarify: what do you mean by "types with internal linkage"? Isn't one of the points that types can't have internal (static?) linkage? – Sergei Tachenov Feb 12 '11 at 11:41
  • 1
    This is probably a mistake on my part. I just checked a C++ standard draft and it seems named types always have external linkage. But the definition of what internal and external linkage means seems a bit contratictory in combination with what anonymous namespaces achieve. – sellibitze Feb 12 '11 at 11:52
  • @sellibitze, my knowledge of the linkage thing is a bit fuzzy, but I have noticed that `readelf -s` outputs LOCAL in the "Bind" column for both static and anonymous-namespaced variables. For global variables it says GLOBAL. But that doesn't stop GCC from allowing anonymous-namespaced variables as template arguments, as opposed to static ones, so your point remains valid. – Sergei Tachenov Feb 12 '11 at 12:08
  • why is the fact that "static means too many things" a good reason why namespaces are superior? – csguy Nov 11 '19 at 01:51
  • @sellibitze, I read "For pointers to objects, the template arguments have to designate the address of a complete object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value." on https://en.cppreference.com/w/cpp/language/template_parameters. How does this resolve with your comment about allowing external linkage only? – DXZ Jun 04 '21 at 14:11
11

One reason may be that static already has too many meanings (I can count at least three). Since an anonymous namespace can encapsulate anything including types, it seems superior to the static solution.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • "_`static` already has too many meanings (I can count at least three)._" I see only 2 **different** meanings. – curiousguy Nov 25 '11 at 05:40
  • 17
    @curiousguy: symbol linkage; local variable persistence; class method. – Greg Hewgill Nov 25 '11 at 05:52
  • 1
    I see "persistent" variable and static member function as cases of the same idea: a declaration is in lexically inside a scope (function or class), but its runtime behaviour is not the usual behaviour of declaration in that scope. BTW, class-specific operator new and delete are usually not declared static, but are always static by definition. – curiousguy Nov 25 '11 at 06:15
  • 3
    @curiousguy: There is namespace-static, which means that the storage for the global object is restricted to the translation unit. There is member-static, which means that the member of the class is not part of the class instance (and static member functions don't get `this`). And there's local-static, which means that the defined variable is persistent across function calls, but it's *lifetime* only starts the first time it is encountered. The lifetime of namespace-static starts at the beginning of the program's execution, before main (just like regular globals). So no, that's 3 definitions. – Nicol Bolas Dec 10 '11 at 22:08
  • 3
    @NicolBolas That's correct, there are 3 definitions that cannot be completely unified, but the last two are related. There are only 2 entirely unrelated uses of `static`: "_restricted to the translation unit_" and "not the normal lifetime rules". – curiousguy Dec 11 '11 at 15:06
6

There are two reasons I think:

  • static has two different meanings: at class scope, it means shared by the whole class while at file/function scope it affects the visibility/storage...
  • unnamed namespaces allow to declare new struct, class and typedef

One note though, the commitee backpedaled on this: static is no longer marked as deprecated in n3225.

sellibitze
  • 27,611
  • 3
  • 75
  • 95
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722