5

namespace { int Foo (int a) ; }

Like this. Is this code snippet legal?

Is this legal? and, can I reference Foo in anywhere? or only certain domain?

Thank you.

Anders Lind
  • 4,542
  • 8
  • 46
  • 59
  • possible duplicate of [Superiority of unnamed namespace over static?](http://stackoverflow.com/questions/4422507/superiority-of-unnamed-namespace-over-static) – Nawaz Oct 06 '11 at 06:50
  • It is legal, but means something different than a regular namespace. :) – jalf Oct 06 '11 at 06:51

3 Answers3

9

It is legal, You can use Foo anywhere in the same Translation Unit.

Anonymous namespace is the standard prescribed way of saying static on variables to limit their scope to the same Translation unit.

C++03 Standard section 7.3.1.1 Unnamed namespaces

para 2:

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


Update:
As @Matthieu M. correctly points out in the comments, and his answer The C++11 Standard removed the above quote from C++03 Standard, which implies that the static keyword is not deprecated when declaring objects in a namespace scope, Anonymous or Unnamed namespaces are still valid nevertheless.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • My answer is slightly different, but a little bit more correct I think ;) – Björn Pollex Oct 06 '11 at 06:44
  • @BjörnPollex: Ah it was my second edit made our answers same lol – Alok Save Oct 06 '11 at 06:45
  • And now we both added standard quotes :) – Björn Pollex Oct 06 '11 at 06:47
  • @BjörnPollex: And then I added link to `What is an Translation Unit` :-) – Alok Save Oct 06 '11 at 06:49
  • @BjörnPollex: Well, let me upvote you too, for your answer came in as quick as was mine & is as accurate as well. C++ Wins :) – Alok Save Oct 06 '11 at 06:55
  • 2
    @Als: your answer is, however, *deprecated*. In C++11, the commitee backed out and the use of the `static` keyword is no longer described as deprecated :) – Matthieu M. Oct 06 '11 at 06:57
  • @MatthieuM.: I don't have the C++11 standard handy right now, but I will look it up and modify accordingly, thanks for the heads up! :) – Alok Save Oct 06 '11 at 07:04
  • @Als: I've reproduced it below (same paragraph) in its entirety. The mention about deprecation has been removed. I think the rationale was that it would be yet another hurdle for compatibility with C. – Matthieu M. Oct 06 '11 at 07:40
  • @MatthieuM.: Yes, you are correct, I had edited the answer to reflect it, the same time while you posted the answer, Now I have edited to link to your answer. Thanks. – Alok Save Oct 06 '11 at 07:44
  • @MatthieuM.: So this means we should still prefer unnamed namespaces to `static`, even though it is no longer deprecated? – Björn Pollex Oct 06 '11 at 08:45
  • @BjörnPollex: I think it means that we are free to do however we please. I must admit that I tend to use `static` when I only have a function or constant to declare, I find it clearer because `static` is right next to the definition so it's clear whether in an unnamed namespace it's not immediately clear. However I do use unnamed namespaces whenever I have class definitions, and in this case I pack all the stuff in there.... call me fickle :D – Matthieu M. Oct 06 '11 at 08:57
5

This is legal. You can reference Foo anywhere inside the translation-unit.

From the C++03-standard, Section 7.3.1.1:

An unnamed-namespace-definition behaves as if it were replaced by

namespace unique { /* empty body */ } using namespace unique;
namespace unique { namespace-body } 

where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program.

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

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • `unnamed-namespace-definition behaves as if it were replaced by ...`. I beg to differ here. In case of unnamed `namespace` you can declare/define a variable inside it. However, in case of normal `namespace` you cannot (because it will cause multiple symbol linker error). So both doesn't have the same effect. – iammilind Oct 06 '11 at 06:53
  • 3
    @iammilind: Since `unique` (which is the name of that namespace) is different for all translation-units, you will never have multiply defined symbols. Also, this is a quote from the standard, so if you beg to differ, take it up with the committee ;) – Björn Pollex Oct 06 '11 at 06:56
  • Ok, I thought `unique` is just a name. I din't know standard committee would put such confusing example :)). May be `namespace { ... } using namespace ;` would have been appropriate wording. – iammilind Oct 06 '11 at 06:59
  • @iammilind: the standard uses a different typeface to indicate that *unique* isn't literally part of the code; I guess they also assumed that people would read to the end of the sentence. – Mike Seymour Oct 06 '11 at 10:34
  • @MikeSeymour, yup agreed. My mistake. And +1 to this answer. Thanks. – iammilind Oct 07 '11 at 02:46
3

The definition changed slightly in the C++11 Standard:

7.3.1.1 Unnamed namespaces [namespace.unnamed]

1/ An unnamed-namespace-definition behaves as if it were replaced by

inlineoptnamespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }

where inline appears if and only if it appears in the unnamed-namespace-definition, all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the entire program.94 [ Example:

namespace { int i; } // unique ::i
void f() { i++; } // unique ::i++

namespace A {
  namespace {
    int i; // A:: unique ::i
    int j; // A:: unique ::j
  }
  void g() { i++; } // A:: unique ::i++
}

using namespace A;

void h() {
  i++; // error: unique ::i or A:: unique ::i
  A::i++; // A:: unique ::i
  j++; // A:: unique ::j
}

—end example ]

Community
  • 1
  • 1
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722