Title
Unclear term "copy/move operation" in specification of copy elision
Status
open
Section
11.9.6 [class.copy.elision]
Submitter
Gabriel Dos Reis

Created on 2024-08-16.00:00:00 last changed 1 month ago

Messages

Date: 2024-08-16.00:00:00

The specification of copy elision in 11.9.6 [class.copy.elision] uses the undefined term "copy/move operation", even though the constructor actually selected might not be a copy or move constructor as specified in 11.4.5.3 [class.copy.ctor]. It is thus unclear whether copy elision can be applied even in the case a non-copy/move constructor is selected.

Possible resolution:

Change in 11.9.6 [class.copy.elision] paragraph 1 through 3 as follows:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of creation of a class object, even if the selected constructor selected for the copy/move operation and/or the destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation initialization as simply two different ways of referring to the same object. If the first parameter of the selected constructor is an rvalue reference to the object's type, the destruction of that object occurs when the target would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects would have been destroyed without the optimization. [ Foonote: Because only one object is destroyed instead of two, and one copy/move constructor is not executed object is not created, there is still one object destroyed for each one constructed. -- end footnote ] This elision of copy/move operations object creation, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
  • in a return statement (8.7.4 [stmt.return]) in a function with a class return type, when the expression is the name of a non-volatile object o with automatic storage duration (other than a function parameter or a variable introduced by the exception-declaration of a handler (14.4 [except.handle])) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation copy-initialization of the result object can be omitted by constructing the object o directly into the function call's return result object;
  • in a throw-expression (7.6.18 [expr.throw]), when the operand is the name of a non-volatile object o with automatic storage duration (other than a function or catch-clause parameter or a variable introduced by the exception-declaration of a handler) that belongs to a scope that does not contain the innermost enclosing compound-statement associated with a try-block (if there is one), the copy/move operation copy-initialization of the exception object can be omitted by constructing the object o directly into the exception object;
  • in a coroutine (9.5.4 [dcl.fct.def.coroutine]), a copy of a coroutine parameter can be omitted and references to that copy replaced with references to the corresponding parameter if the meaning of the program will be unchanged except for the execution of a constructor and destructor for the parameter copy object;
  • when the exception-declaration of a handler (14.4 [except.handle]) declares an object o of the same type (except for cv-qualification) as the exception object (14.2 [except.throw]), the copy operation copy-initialization of o can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration. [Note 1: There cannot be a move from the exception object because it is always an lvalue. —end note]
History
Date User Action Args
2024-08-16 00:00:00admincreate