6

I've written the following code:

   #include <iostream>

    inline namespace M
    {
        int j=42;
    }

    int main(){ std::cout << j << "\n"; } //j is unqualified name here. 
                 //Hence, unqualified name lookup rules will be applied.
                 //This implies that member of inline namespace shall not be considered. 
                 //But it is not true

And it works fine. But I'm expected that the that program is ill-formed. It is because the Standard said (N3797, sec. 7.3.1/7):

Finally, looking up a name in the enclosing namespace via explicit qualification (3.4.3.2) will include members of the inline namespace brought in by the using-directive even if there are declarations of that name in the enclosing namespace.

Also the section 3.4.1/6 does not said anything about involving of inline namespace in the unqualified name lookup:

A name used in the definition of a function following the function’s declarator-id 28 that is a member of namespace N (where, only for the purpose of exposition, N could represent the global scope) shall be declared before its use in the block in which it is used or in one of its enclosing blocks (6.3) or, shall be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in one of N’s enclosing namespaces.

It is a g++ bug or I understood that rules incorrectly?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304

1 Answers1

4

There's no bug..

No, it's not a bug in neither g++ (or clang++) which has the behavior described, the compiler is supposed to find j.

inline namespace N {
  int j;
}

int main () {
  int a = j; // legal, `j` == `N::j`
}

What does the Standard say?

You are missing a very important section of the standard, namely 7.3.1§8, where it states that the enclosing namespace of an inline namespace implicitly has a using directive that refers to the inline namespace.

[7.3.1]p8 namespace definition [namespace.def]

Members of an inline namespace can be used in most respects as thought they were members of the enclosing namespace. Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lookup (3.4.2) whenever one of them is, and a using-directive (7.3.4) that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace (7.3.1.1).


Elaboration

This means that our previous example is semantically equivalent to the below, where we have introduced a using-directive to bring the names from our nested namespace into the global namespace:

inline namespace N {
  int j;
}

using namespace N; // the implicit using-directive    

int main () {
  int a = j; // legal
}
Community
  • 1
  • 1
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196