Skip to content

Unclear words regarding mandatory copy-elision during initialization with identical types (since C++17). #8336

@EugeneZavidovskyi

Description

@EugeneZavidovskyi

So there is a phrase from the C++ Standard working draft (n4928):

[dcl.init.general] ¶ 16.6.1

If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same as the destination type, the initializer expression is used to initialize the destination object [Example 2: T x = T(T(T())); value-initializes x. — end example]

For me, the words "is used to initialize" sounds like an infinite recursion of "the process of initialization" mentioned in [dcl.init.general] ¶ 1. Yes, I re-read carefully [basic.lval] ¶ 5 and [expr.type.conv] and understand now why the reader of the Standard is supposed to think that neither copy- nor move-constructors of T are called. But again the wording in [dcl.init.general] ¶ 16.6.1 could be improved like this:

[dcl.init.general] ¶ 16.6.1 (corrected)

If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same as the destination type, the result object of the initializer expression is the object being initialized. [Example 2: T x = T(T(T())); x is value-initialized according to [expr.type.conv] and [basic.lval]. — end example]

[dcl.init.general] ¶ 16.9 (corrected)

Otherwise, the result object of the (possibly converted) initializer expression is the object being initialized.

[basic.lval] ¶ 5 (corrected)

...The result object of a prvalue is the object initialized by the prvalue and the initial value of which is that of the prvalue; (italicized words - sic!)...

Another (minimal change) variant is to add a few words to the example in:

[dcl.init.general] ¶ 16.6.1 (corrected)

...the initializer expression is used to initialize the destination object. [Example 2: T x = T(T(T())); x is value-initialized according to [expr.type.conv] and [basic.lval]. — end example]

This part of the Standard is important, because it makes mandatory the so called unnamed return value optimization (URVO) for compilers since C++17...

Discussion is also on Stack Overflow here.

Metadata

Metadata

Assignees

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