Skip to content

CWG2809 [dcl.fct.def.default] Clarify that the implicitly generated definition does not redeclare the function #434

@t3nsor

Description

@t3nsor

Full name of submitter: Brian Bi

Reference (section label): [dcl.fct.def.default]

Issue description: [dcl.fct.def.default]/5 states:

[...] A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.
A non-user-provided defaulted function (i.e., implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) or needed for constant evaluation ([expr.const]).

In the first case (the function is user-provided), there is a second point of declaration for the function, wherever the user wrote the definition. The juxtaposition of these two sentences may give the impression that, in the second case (a non-user-provided defaulted function), there is also second point of declaration at the point where the function is odr-used or needed for constant evaluation. The only hint that this is not the case is the use of the word "when" rather than "where". This is very subtle and I think it should be called out in a note.

(The "second point of declaration" interpretation would cause a bizarre situation in which, in the case of a hidden friend comparison operator that is defaulted at its first declaration, after the first reference to that operator that causes it to be implicitly defined, it would no longer be a hidden friend. No compiler actually takes such an interpretation.)

Suggested resolution: Modify [dcl.fct.def.default]/5 as shown:

Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor], [class.dtor], [class.copy.ctor], [class.copy.assign]) as described below, including possibly defining them as deleted. A defaulted prospective destructor ([class.dtor]) that is not a destructor is defined as deleted. A defaulted special member function that is neither a prospective destructor nor an eligible special member function ([special]) is defined as deleted.
A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.
[Note 1: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note]
A non-user-provided defaulted function (i.e., implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) or needed for constant evaluation ([expr.const]).
[Note 1: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note]
[Note 2: The implicit definition of a non-user-provided defaulted function does not reintroduce that function. — end note]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions