Title
Unintended ambiguity in inline namespace lookup
Status
cd2
Section
6.5.5.3 [namespace.qual]
Submitter
Michael Wong

Created on 2009-04-07.00:00:00 last changed 178 months ago

Messages

Date: 2010-03-15.00:00:00

[Voted into WP at March, 2010 meeting as part of document N3079.]

Date: 2009-11-15.00:00:00

Proposed resolution (November, 2009):

  1. Change 9.8.2 [namespace.def] paragraph 9 as follows:

  2. These properties are transitive: if a namespace N contains an inline namespace M, which in turn contains an inline namespace O, then the members of O can be used as though they were members of M or N. The transitive closure of all inline namespaces in N is the inline namespace set of N. The set of namespaces consisting of the innermost non-inline namespace enclosing an inline namespace O, together with any intervening inline namespaces, is the enclosing namespace set of O.
  3. Insert a new paragraph before 6.5.5.3 [namespace.qual] paragraph 2 and change the existing paragraph 2 as follows:

  4. 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 (9.8.2 [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.

    Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), let S be the set of all declarations of m in X and in the transitive closure of all namespaces nominated by using-directives in X and its used namespaces, except that using-directives that nominate non-inline namespaces (9.8.2 [namespace.def]) are ignored in any namespace, including X, directly containing one or more declarations of m. No namespace is searched more than once in the lookup of a name. If 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 (9.9 [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. [Example:...

Date: 2009-04-07.00:00:00

The algorithm for namespace-qualified lookup is given in 6.5.5.3 [namespace.qual] paragraph 2:

Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), let S be the set of all declarations of m in X and in the transitive closure of all namespaces nominated by using-directives in X and its used namespaces, except that using-directives that nominate non-inline namespaces (9.8.2 [namespace.def]) are ignored in any namespace, including X, directly containing one or more declarations of m.

Consider the following example:

    namespace A {
        inline namespace B {
            namespace C {
                int i;
            }
            using namespace C;
        }
        int i;
    }

    int j = A::i;     // ambiguous

The transitive closure includes B because it is inline, and it includes C because there is no declaration of i in B. As a result, A::i finds both the i declared in A and the one declared in C, and the lookup is ambiguous.

This result is apparently unintended.

History
Date User Action Args
2010-03-29 00:00:00adminsetmessages: + msg2661
2010-03-29 00:00:00adminsetstatus: tentatively ready -> cd2
2010-02-16 00:00:00adminsetstatus: drafting -> tentatively ready
2009-11-08 00:00:00adminsetstatus: ready -> drafting
2009-08-03 00:00:00adminsetmessages: + msg2138
2009-08-03 00:00:00adminsetstatus: open -> ready
2009-04-07 00:00:00admincreate