Movatterモバイル変換


[0]ホーム

URL:


This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-12-20


125. Ambiguity infriend declaration syntax

Section:_N4567_.5.1.1  [expr.prim.general]    Status:CD1    Submitter:Martin von Loewis    Date:7 June 1999

[Voted into WP at March 2004 meeting.]

The example below is ambiguous.

    struct A{      struct B{};    };    A::B C();    namespace B{      A C();    }    struct Test {      friend A::B ::C();    };
Here, it is not clear whether the friend declaration denotesA B::C() orA::B C(), yet the standard does not resolve thisambiguity.

The ambiguity arises since both thesimple-type-specifier(9.2.9.3 [dcl.type.simple] paragra 1) and aninit-declararator(9.3 [dcl.decl] paragraph 1)contain an optional:: and an optionalnested-name-specifier(_N4567_.5.1.1 [expr.prim.general] paragraph 1).Therefore, two different ways to analyse this code arepossible:

simple-type-specifier =A::B
init-declarator =::C()
simple-declaration =friend A::B ::C();
or
simple-type-specifier =A
init-declarator =::B::C()
simple-declaration =friend A ::B::C();
Since it is a friend declaration, the init-declarator may bequalified, and start with a global scope.

Suggested Resolution: In the definition ofnested-name-specifier, add asentence saying that a:: token immediately following anested-name-specifier is always considered as part of thenested-name-specifier. Under this interpretation, the example isill-formed, and should be corrected as either

    friend A (::B::C)();   //or    friend A::B (::C)();

An alternate suggestion — changing9.2 [dcl.spec] to say that

The longest sequence oftokens that could possibly be a typename is taken as thedecl-specifier-seq of adeclaration.

— is undesirable because it would make the example well-formedrather than requiring the user to disambiguate the declarationexplicitly.

Proposed resolution (04/01):

(See below for problem with this, from 10/01 meeting.)

In _N4567_.5.1.1 [expr.prim.general] paragraph 7,

  1. Before the grammar forqualified-id, start a newparagraph 7a with the text

    Aqualified-id is anid-expression that contains thescope resolution operator::.
  2. Following the grammar fragment, insert the following:

    The longest sequence of tokens that could form aqualified-idconstitutes a singlequalified-id. [Example:

        // classes C, D; functions F, G, namespace N; non-class type T    friend C ::D::F();   // ill-formed, means friend (C::D::F)();    friend C (::D::F)(); // well-formed    friend N::T ::G();   // ill-formed, means friend (N::T::G)();    friend N::T (::G)(); // well-formed

    end example]

  3. Start a new paragraph 7b following the example.

(This resolution depends on that ofissue 215.)

Notes from 10/01 meeting:

It was pointed out that the proposed resolution does not deal withcases likeX::Y whereX is a type but not a class type.The working group reaffirmed its decision that the disambiguation shouldbe syntactic only, i.e., it should depend only on whether or not the name is atype.

Jason Merrill:

At the Seattle meeting, I suggested that a solution might be to change theclass-or-namespace-name in thenested-name-specifierrule to just be"identifier"; there was some resistance to this idea. FWIW, I've triedthis in g++. I had to revise the idea so that only the second andsubsequent names were open to being any identifier, but that seems to workjust fine.

So, instead of

it would be

Or some equivalent but right-associative formulation, if people feel that'simportant, but it seems irrelevant to me.

Clark Nelson:

Personally, I prefer the left-associative rule. I think it makes it easierto understand. I was thinking about this production a lot at the meeting,considering also some issues related to301.My formulation was getting kindof ugly, but with a left-associative rule, it gets a lot nicer.

Your proposal isn't complete, however, as it doesn't allow templatearguments without an explicit template keyword. You probably want to add analternative for:

There is admittedly overlap between this alternative and

but I think they're both necessary.

Notes from the 4/02 meeting:

The changes look good. Clark Nelson will merge the two proposalsto produce a single proposed resolution.

Proposed resolution (April 2003):

nested-name-specifier is currently defined in_N4567_.5.1.1 [expr.prim.general] paragraph 7 as:

The proposed definition is instead:

Issue 215is addressed by usingtype-name instead ofclass-name in the first alternative.Issue 125 (this issue)is addressed by usingidentifier instead of anything more specific in the third alternative.Using left association instead of right association helps eliminate the need forclass-or-namespace-name (ortype-or-namespace-name, as suggested forissue 215).

It should be noted that this formulation also rules out the possibility ofA::template B::, i.e. using thetemplate keyword without any template arguments.I think this is according to the purpose of thetemplate keyword, and that the former rule allowed such a construct only because of the difficulty of formulation of a right-associative rule that would disallow it.But I wanted to be sure to point out this implication.

Notes from April 2003 meeting:

See alsoissue 96.

The proposed change resolves only part ofissue 215.




[8]ページ先頭

©2009-2026 Movatter.jp