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.
Related
Consider this code:
namespace A
{
int i = 24;
}
namespace B
{
using namespace A;
int i = 11;
int k = i; // finds B::i, no ambiguity
}
And basic.lookup.unqual.2:
§6.4.1 Unqualified name lookup [basic.lookup.unqual]
The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see
[namespace.udir]. For the purpose of the unqualified name lookup rules
described in [basic.lookup.unqual], the declarations from the
namespace nominated by the using-directive are considered members of
that enclosing namespace.
For me the standard says pretty clear that for the purpose of unqualified name lookup (the i in int k = i) the declaration of i from A is considered member of B so i should be ambiguous in int k = i, however both gcc and clang compile and resolve i to the local B::i. I have searched the standard (basic.scope.hiding and namespace.udir) and did not find an exception or a rule to contradict the above one. I have found that for qualified name lookup, but not for unqualified name lookup.
Why is i unambiguous?
The key is 10.3.4/2 "During unqualified name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace."
The nominated namespace is A, the using directive is in B, and the smallest (in fact only) common namespace is the global namespace. Thus i appears as if declared in the global namespace, and is hidden by B::i.
I'm wondering if this is allowed:
namespace A {
inline namespace B {
int a;
}
int a;
}
void foo() {
A::a = 0; // clang 3.4 compiles, but gcc doesn't
}
Standard says, that
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.
But I can't get it.
It looks like this was a pre clang 3.5 bug and there are two defect reports on this 812 and 861. The resolution is in 861 and adds the following to 3.4.3.2 [namespace.qual] (emphasis mine going forward):
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 [namespace.def]). 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 non-inline namespaces Ni nominated by using-directives in X and its inline namespace set.
and the also relevant additions:
if S(X,m) is the empty set, the program is ill-formed. Otherwise, if S(X,m) has exactly one member, or if the context of the reference is a using-declaration (7.3.3 [namespace.udecl]), S(X,m) is the required set of declarations of m. Otherwise if the use of m is not one that allows a unique declaration to be chosen from S(X,m), the program is ill-formed.
It looks like the change was added pre C++11, this text is present in N3337.
Consider the following two code snippets:
Snippet A
#include <iostream>
namespace
{
bool foo = false;
}
bool foo = true;
int main()
{
std::cout << foo << std::endl;
}
Snippet B
#include <iostream>
namespace A
{
namespace
{
bool foo = false;
}
bool foo = true;
}
int main()
{
std::cout << A::foo << std::endl;
}
In Snippet A, foo's usage inside int main() is ambiguous, whilst in Snippet B it is not. Why is this the case?
Related: Anonymous Namespace Ambiguity
The behavior of unnamed namespaces is specified in §7.3.1.1 [namespace.unnamed]/p1:
An unnamed-namespace-definition behaves as if it were replaced by
inline_opt namespace 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.
In particular, note that the declarations inside the unnamed namespace is made visible in the surrounding scope via a using-directive using namespace unique;.
In Snippet A, foo is unqualified, so the compiler performs unqualified name lookup (§3.4.1 [basic.lookup.unqual]). Relevant here is paragraph 2 of the subclause:
2 The declarations from the namespace nominated by a using-directive
become visible in a namespace enclosing the using-directive; see
7.3.4. For the purpose of the unqualified name lookup rules described in 3.4.1, the declarations from the namespace nominated by the
using-directive are considered members of that enclosing namespace.
Hence, unqualified name lookup finds both declarations of foo, and the name is ambiguous.
In Snippet B, A::foo is qualified, so qualified name lookup rules apply. Since A is a namespace, the applicable subclause is §3.4.3.2 [namespace.qual]. As relevant here, the rule is specified in paragraph 2 of that subclause:
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.
In other words, qualified name lookup considers namespaces nominated by using-directives only if the name is not found in the specified namespace and its inline namespace set. Here, the name foo is found in namespace A, so the unnamed namespace nominated by the using-directive is not considered, and there's no ambiguity.
If you write ::foo instead of foo in Snippet A, then qualified lookup rules would apply instead, and there would once again be no ambiguity.
I want to understand the namespace qualified name lookup rule. I'm trying to do that on the example:
namespace A
{
int a=::b; //error: ‘::b’ has not been declared
}
int b=6;
There is a quote which I rely in my reasoning (3.4.3.2/2 N3797):
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.
Let X be a global scope. We have that S(X,b)={int b=6}. This implies that name lookup must be success. But in fact, the program is ill-formed. Might I don't understood this rule correctly?
b is in global scope but it must be declare before where you are using it.
like
int b=6;
namespace A
{
int a=::b;
}
(N 3690 Draft)
3.4.1 Unqualified name lookup
4. A name used in global scope, outside of any function, class or user-declared namespace, shall be declared before its use in global scope.
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.