Name lookup of first namespace name in nested-name-specifier? - c++

Given a nested-name-specifier A:: in a translation unit that doesn't have any classes, templates, enumerations, or typedefs, if well-formed, the identifier A must refer to a namespace.
For example:
namespace X
{
int i;
}
int main()
{
X::i = 42; // Here X:: is a nested-name-specifier
// and X is a namespace-name
// i is looked up qualified w.r.t. X
}
In the above example A is X, however my question is about the general case.
How does name lookup proceed for a namespace-name A in A::?
The name lookup rules are summarized in 3.4, but it isn't clear to me how (or which ones) that apply in such a situation.
For example, is the lookup of A an unqualified name lookup? Does 3.4.1 apply to it?
Put another way: Which namespaces are searched for a namespace named A, and in what order? How did you conclude this from the standard?

Yes, A is a regular unqualified name lookup per 3.4.1, successively searching the scopes enclosing the nested-name-specifier, with the exception that only classes and namespace names are found. For example, you could have this:
int main()
{
int X;
X::i = 42; // OK, int X not found.
}
http://ideone.com/NaEIVd
Actually using this loophole is not recommended; if X were an object of class type then X::i and X.i could be completely different things.
To arrive at this conclusion from the Standard, start at 3.4.3 (qualified lookup, which is the high-level construct we're ultimately analyzing), which says in paragraph 1,
The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (5.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.
Reading on to paragraph 2, it doesn't apply because the qualified-id isn't being declared. The remaining paragraphs likewise specify inapplicable exceptions. So, what is the thing preceding the ::? Refer to the grammar.
nested-name-specifier:
::
type-name ::
namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
Only type-name :: and namespace-name :: match our a priori criteria. Also these overlap with what we've found so far. How is a type-name or namespace-name usually resolved in a particular context? Unqualified lookup. Proceed to 3.4.1.
First, 3.4.1/1 is a general rule to bear in mind:
In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
The next applicable paragraph is 6:
A name used in the definition of a function following the function’s declarator-id 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.
This rule doesn't tell us to actually search in the global namespace for the name, but it does mention the function's enclosing namespace (in this case the global one) in a list, and paragraph 1 says to search listed namespaces. So that's sufficient to construct a name lookup.
What it surprisingly doesn't do is mention a recursive search prioritizing inner, enclosed namespaces, but you don't actually have such a thing in your example so I'll stop here :) . It's much faster to leave compiling to the compiler, and work manually only in case of a problem.

In the example you gave, X would be considered an unqualified name lookup. And as such it does follow the rules in 3.4.1
In this case the namespaces searched are as follows:
The local namespace of the main() function prior to the definition. (In which a namespace may not be defined per 7.3.1.4.)
The global namespace.
I'm afraid I can't point to a place in the standard where it specifically says namespace names are the same as any other name. But they are. The name lookup doesn't know that's a namespace name (it could be a class name or a struct name) until it actually finds a namespace with that name.

Related

Inferring namespace of freestanding function

Question on namespace qualification: Why isn't the namespace of the function inferred below?
namespace X {
void func(int) {}
struct Z{
void func(){
//func(int{}); does not compile
X::func(int{}); // this works
}
};
}
int main() {
X::Z z;
z.func();
}
This specific part of C++ can be generally called "unqualified name lookup". This term describes taking a single identifier in a C++ program and then determining which actual type, or object, or function, or class, it is referencing.
For example, there can be many things called rosebud in a C++ program, so
rosebud();
This can reference a class method of this name, and this calls it. Or this could be an object with an overloaded () operator, which invokes it. There could also be something called rosebud() in a different namespace. Unqualified name lookup specifies which one of these this particular rosebud references.
struct Z{
void func(){
Here we're in a method of class Z. Unqualified name lookup first looks for identifiers that are members of this class. Only if it's not found then does unqualified name lookup looks in the global namespace, to see if something is there.
func(int{}); // does not compile
Well, there happens to be a method with the name func in this class, so this func's unqualified name lookup resolves to this method. This fails, because that func method takes no parameters.
Unqualified name lookup considers where exactly the unqualified identifier occurs. When it occurs in a class, unqualified name lookup searches the class's members, first.
Even though there's also a func function in the global scope, unqualified lookup finds the class method, and that's it (quoting from the cited link):
[unqualified] name lookup examines the scopes as described below,
until it finds at least one declaration of any kind, at which time the
lookup stops and no further scopes are examined.
End of the road. The fact that there's also a func in the global namespace is immaterial. For unqualified name lookup, once "something" is found, it better work, or else.
These are just one of the rules of unqualified name lookup.
X::func(int{}); // this works
Well, yes. This explicitly references func in the X namespace. This symbol is (partially) qualified with an explicit namespace reference.

Why is the ADL not working when `using directive` is used?

Here is a similar question, but in this question it works, however, it fails in the following circumstance, why?
namespace A
{
int k;
}
namespace B
{
class test{};
void k(const test&){/*do something*/}
}
int main()
{
using namespace A;
k(B::test());//compile error
}
Error message is: "'A::k' cannot be used as a function" (gcc 6.3.0)
That is to say, the compiler does not try to do ADL and never find the void k(const test&) in namespace B
However, I think the ADL should work in such situation because the code above does not belong to the following circumstance:
quoted from cppref
First, the argument-dependent lookup is not considered if the lookup set produced by usual unqualified lookup contains any of the following:
1) a declaration of a class member
2) a declaration of a function at block scope (that's not a using-declaration)
3) any declaration that is not a function or a function template (e.g. a function object or another variable whose name conflicts with the name of the function that's being looked up)
To be more precise, here the using namespace A does not introduce any declaration:
quoted from cppref
Using-directive does not add any names to the declarative region in which it appears (unlike the using-declaration), and thus does not prevent identical names from being declared.
The name lookup for a function call has two parts:
normal unqualified lookup
ADL
According to N4659 [basic.lookup.argdep]/3, the normal unqualified lookup happens first; and then ADL stage does not go ahead if the normal unqualified lookup found:
a declaration of a class member, or
a block-scope function declaration that is not a using-declaration, or
a declaration that is neither a function nor a function template.
In your code the normal unqualified lookup does find A::k as discussed in your previous question. So ADL does not happen for this code.
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup (6.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
So, unqualified name lookup will find A::k, that is the reason for the error.

Why does the name lookup does not stop when it finds the entity implicitly declared by using directive?

Here is the code example:
#include<iostream>
using namespace std;
namespace B
{
int ohoh=2;
}
namespace A
{
int ohoh=666;
namespace C
{
//using B::ohoh;(as if declared by using directive) //why does the lookup not stops here?
int foo()
{
using namespace B;
cout<<ohoh<<endl;
}
}
}
int main()
{
A::C::foo();
}
The output is 666 but not 2. Why?
Quoted from cppref
For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined. (Note: lookup from some contexts skips some declarations, for example, lookup of the name used to the left of :: ignores function, variable, and enumerator declarations, lookup of a name used as a base class specifier ignores all non-type declarations)
For the purpose of unqualified name lookup, all declarations from a namespace nominated by a using directive appear as if declared in the nearest enclosing namespace which contains, directly or indirectly, both the using-directive and the nominated namespace.
From the quoted paragraph above ,the name lookup should stop at nearest namespace C ,Where I've commented in the code.Why does it does not stop and find A::ohoh ?
By the way,I think I should use the using directive as little as possible.
For the purpose of unqualified name lookup, all declarations from a namespace nominated by a using directive as if declared in the nearest enclosing namespace which contains [...] both the using-directive and the nominated namespace.
In this case, the nearest namespace that contains both B and the using-directive is the global namespace. Therefore, all names from B appear inside A::C::foo as if they were declared in the global namespace. When searching for the name ohoh, A is searched before the global namespace, so A::ohoh is the first declaration found and name lookup stops there.

Name lookup in using-declaration via using-directive

Is the following program well-formed or ill-formed according to the c++ standard?
namespace N { int i; }
using namespace N;
using ::i;
int main() {}
I get different results with different compilers:
Clang (http://melpon.org/wandbox/permlink/c8vl7XbumyyS6vsw): No errors.
GCC (http://melpon.org/wandbox/permlink/immhNeWFCMcCA800): Error: 'i' not declared.
Is this program well-formed or ill-formed according to the c++ standard? References to the c++ standard needed.
I'm trying to figure out for which compiler I should file a bug.
Well-formed.
The using-directive doesn't introduce the name i in the global namespace, but it is used during lookup. The using-declaration uses qualified lookup to find i; qualified lookup in the presence of using-directives is specified in [3.4.3.2 p1, p2] (quotes from N4527, the current working draft):
If the nested-name-specifier of a qualified-id nominates a namespace
(including the case where the nested-name-specifier is ::, i.e.,
nominating the global namespace), the name specified after the
nested-name-specifier is looked up in the scope of the namespace. [...]
For a namespace X and name m, the namespace-qualified lookup set
S(X,m) is defined as follows: Let S'(X,m) be the set of all
declarations of m in X and the inline namespace set of X (7.3.1). If
S'(X,m) is not empty, S(X,m) is S'(X,m); otherwise, S(X,m) is the
union of S(Ni,m) for all namespaces Ni nominated
by using-directives in X and its inline namespace set.
So, for qualified lookup, the first step is to look for declarations of i made directly in the namespace indicated by the nested-name-specifier (:: in this case). There are no such declarations, so lookup then proceeds to the second step, which is to form the set of all declarations of i found by qualified lookup in all namespaces nominated by using-directives in the global namespace. That set is comprised of N::i, which is the result of name lookup, and is introduced as a name in global namespace by the using declaration.
I find it worth noting (although pretty obvious) that this definition of qualified lookup is recursive: using the notation in the quote, qualified lookup in each namespace Ni will first look for declarations made directly in Ni, then, if none is found, will in turn proceed to look in the namespaces nominated by using-directives in Ni, and so on.
For what it's worth, MSVC accepts the code as well.
GCC is wrong. Qualified name lookup does consider N::i; §3.4.3.2/2 & /3:
For a namespace X and name m, the namespace-qualified lookup set
S(X, m) is defined as follows: Let S'(X, m) be the set of all
declarations of m in X and the inline namespace set of X
(7.3.1). If S'(X, m) is not empty, S(X, m) is S'(X, m);
otherwise, S(X, m) is the union of S(Ni, m) for all namespaces Ni nominated by using-directives in X
and its inline namespace set.
Given X::m (where X is a user-declared namespace), or given ::m (where
X is the global namespace), […] if S(X, m) has exactly one member, or if the
context of the reference is a using-declaration (7.3.3), S(X, m) is
the required set of declarations of m.
There is only one namespace nominated by a using-directive in your program: N. It's therefore included in the union and ::i is resolved to N::i.
Note that GCC is inconsistent with its lookup: Using ::i in another context is fine.
namespace N { int i; }
using namespace N;
int main() {
::i = 5;
}
This compiles. The only difference that a using-declaration makes as a context is shown in the above quote and does not affect the established conclusion.

Overload Resolution: How is this not ambiguous?

Suppose we have this code, copied from a separate question:
namespace x
{
void f()
{
}
class C
{
void f()
{
using x::f;
f(); // <==
}
};
}
The name f on the indicated line unambiguously refers to x::f (at least according to both gcc and clang). Why is x::f preferred over x::C::f in this case? Shouldn't it be ambiguous as both names are visible?
Because the using declaration brings x::f into the scope of f, which is narrower than that of C. Unqualified lookup considers the local block scope, finds a match, and stops before considering the wider class scope. There is no argument-dependent lookup since there are no function arguments, so no further scopes are considered.
#MikeSeymour's answer is spot on; here are the relevant standard quotes (C++11, emphasis mine):
13.3.1.1.1/3:
In unqualified function calls, the name is not qualified by an -> or . operator and has the more general form
of a primary-expression. The name is looked up in the context of the function call following the normal rules
for name lookup in function calls (3.4). The function declarations found by that lookup constitute the set of
candidate functions. Because of the rules for name lookup, the set of candidate functions consists (1) entirely
of non-member functions or (2) entirely of member functions of some class T. ...
3.4.1/1:
In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the
respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is
found, the program is ill-formed.
3.4.1/8
A name used in the definition of a member function (9.3) of class X following the function's declarator-id
... shall be declared in one of
the following ways:
before its use in the block in which it is used or in an enclosing block (6.3), or
shall be a member of class X or be a member of a base class of X (10.2), or
...
From 3.4.1/8, we see that a declaration for the name f (such as the declaration using x::f;) in the block in which it's used is listed earlier than f as the member of class C. As per 3.4.1/1, the earlier one is chosen, so the entire lookup resolves to x::f introduced by the using declaration.
I think that these quotes from the C++ Standard will be relevant:
From the C++ Standard (7.3.3 The using declaration)
13 Since a using-declaration is a declaration, the restrictions on
declarations of the same name in the same declarative region (3.3)
also apply to using-declarations.
And (3.3.7 Class scope)
4) A name declared within a member function hides a declaration of the
same name whose scope extends to or past the end of the member
function’s class.