6
votes

I was looking over section 7.3.1.1 in the C++03 standard expecting to find some description of the access rules for items defined in an unnamed namespace.

The rules seem to be a little different for unnamed namespaces, since you cannot fully qualify access to items in one. I know that at least within the same translation unit, one can access items in an unnamed namespace as if they were not in a namespace. For example:

namespace {
  int foo;
}

void something()
{
  foo = 4;
}

If the namespace had a name, you could not do this. So, where are the rules defined in the standard for these exceptional rules that apply to unnamed namespaces?

2
The anon namespace only says that it will only be seen within the same translation unit. All other namespace rules should apply. You can put things in another namespace and an anon one as well. namespace bar { namespace { int r; }} for instance.Tom Kerr

2 Answers

7
votes

An anonymous namespace is basically treated as:

namespace unique_per_TU
{
    // Stuff
}
using namespace unique_per_TU;

I'll try to find the reference here in a minute.

EDIT:

It appears you already found it in 7.3.1.1/1

An unnamed namespace definition behaves as if it were replaced by

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

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 "fake" using already brings the namespace members into the global namespace as you discovered.

3
votes

Apart from the standard quote which defines Unnamed Namespaces in 7.3.1.1/1,
This is explicitly stated in one of the examples in

3.3.5/1 Namespace Scope:

The declarative region of a namespace-definition is its namespace-body. The potential scope denoted by an original-namespace-name is the concatenation of the declarative regions established by each of the namespace-definitions in the same declarative region with that original-namespace-name. Entities declared in a namespace-body are said to be members of the namespace, and names introduced by these declarations into the declarative region of the namespace are said to be member names of the namespace. A namespace member name has namespace scope. Its potential scope includes its namespace from the name’s point of declaration (3.3.1) onwards; and for each using-directive (7.3.4) that nominates the member’s namespace, the member’s potential scope includes that portion of the potential scope of the using-directive that follows the member’s point of declaration.

>[Example:
namespace N {
      int i;
      int g(int a) { return a; }
      int j();
      void q();
}
namespace { int l=1; }
// the potential scope of l is from its point of declaration
// to the end of the translation unit

namespace N {
    int g(char a) // overloadsN::g(int)
    {
        return l+a; // l is from unnamed namespace
    }
    int i; // error: duplicate definition
    int j(); // OK: duplicate function declaration
    int j() // OK: definition ofN::j()
    {
       return g(i); // callsN::g(int)
    }
    int q(); // error: different return type
}

—end example]

Note the wordings:
the potential scope of l is from its point of declaration to the end of the translation unit