Title
Grammar ambiguity for nodeclspec-function-declaration
Status
tentatively ready
Section
9.1 [dcl.pre]
Submitter
lprv

Created on 2025-10-15.00:00:00 last changed 2 weeks ago

Messages

Date: 2026-10-07.20:41:18

Proposed resolution (approved by CWG 2026-10-06):

  1. Change in 9.1 [dcl.pre] paragraph 11 as follows:

    A nodeclspec-function-declaration shall declare a constructor, destructor, or conversion function. A name-declaration that has the form of a nodeclspec-function-declaration is interpreted as a nodeclspec-function-declaration if and only if its declarator-id has one of the forms specified for the declaration of a constructor, destructor, or conversion function at namespace scope (11.4.5.1 [class.ctor.general], 11.4.7 [class.dtor], 11.4.8.3 [class.conv.fct]).

    [Note 6: Because a member function cannot be subject to a non-defining declaration outside of a class definition (11.4.2 [class.mfct]), a nodeclspec-function-declaration can only be used in a template-declaration (13.1 [temp.pre]), explicit-instantiation (13.9.3 [temp.explicit]), or explicit-specialization (13.9.4 [temp.expl.spec]). —end note]

    [ Example:

      struct A {};
      struct B : A {};
      B::B(A); // error: out-of-line non-defining constructor declaration
      B::A(A); // OK, declares a variable named `A` having type `A`
    

    -- end example]

  2. Change in 11.4.5.1 [class.ctor.general] paragraph 1 as follows:

    A declarator declaration declares a constructor if it is a function declarator (9.3.4.6 [dcl.fct]) of
    • in a friend declaration ([class.friend]), the declarator-id is a qualified-id that names a constructor ([class.qual]);
    • otherwise, in a member-declaration that belongs to the member-specification of a class or class template, the declarator-id is the injected-class-name ([class.pre]) of the immediately-enclosing entity;
    • otherwise, the declarator-id is a qualified-id whose unqualified-id is the injected-class-name of its lookup context.
    The declarator of a constructor declaration shall have the form
    ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt
    
    where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses. , and the id-expression has one of the following forms:
    • in a friend declaration (11.8.4 [class.friend]), the id-expression is a qualified-id that names a constructor (6.5.5.2 [class.qual]);
    • otherwise, in a member-declaration that belongs to the member-specification of a class or class template, the id-expression is the injected-class-name (11.1 [class.pre]) of the immediately-enclosing entity;
    • otherwise, the id-expression is a qualified-id whose unqualified-id is the injected-class-name of its lookup context.
Date: 2026-04-29.21:28:40

CWG 2026-04-28

See also issue 3160.

Date: 2025-11-15.00:00:00

Possible resolution (November, 2025) [SUPERSEDED]:

Change in 9.1 [dcl.pre] paragraph 11:

An ambiguity can arise in a declaration when a type-name is enclosed in parentheses. In this case, the choice is between a nodeclspec-function-declaration with an unnamed parameter and a variable declaration with extra parentheses around the declarator-id. The resolution is to consider the declaration a nodeclspec-function-declaration if its declarator-id is a qualified-id and a variable declaration otherwise. A nodeclspec-function-declaration shall declare a constructor, destructor, or conversion function. [Note 6: Because a member function cannot be subject to a non-defining declaration outside of a class definition (11.4.2 [class.mfct]), a nodeclspec-function-declaration can only be used in a template-declaration (13.1 [temp.pre]), explicit-instantiation (13.9.3 [temp.explicit]), or explicit-specialization (13.9.4 [temp.expl.spec]). —end note]
Date: 2025-10-15.00:00:00

(From submission #741.)

Consider:

  class A;
  A(A);   // #1

#1 can be interpreted as either a nodeclspec-function-declaration or a variable declaration with extra parentheses. A disambiguation rule is missing.

History
Date User Action Args
2026-10-07 20:41:18adminsetstatus: drafting -> tentatively ready
2026-10-06 17:01:54adminsetmessages: + msg8699
2026-04-29 21:28:40adminsetmessages: + msg8558
2026-04-29 21:28:40adminsetstatus: open -> drafting
2026-03-10 22:12:14adminsetmessages: + msg8503
2025-10-15 00:00:00admincreate