(c++20; Working Draft N4868)
[stmt.return]/2 says that the return statement initializes the glvalue result or prvalue result object by copy initialization
the return statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization (9.4) from the operand.
For class types, the return statement "invokes" the selected constructor and copy-initialize the variable obj, the result object of the invocation, because the copy-elision (an implementation is the caller to pass the address of the dest, so that the called function initialize the dest by constructor call)
class MyClass {
int x;
};
MyClass func() {
return MyClass(); //initializes the result object of the function call
}
int main() {
MyClass obj {func()}; //obj is the result object of func().
}
[dcl.init.general]/16.6.1 suggests:
If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object
For fundamental types like int, double, etc., the common implementation is the return statement to copy the operand (return expression) to the registers
(gcc 12.1 -std=c++20)
int func() {
return 2;
}
int main() {
int myInt {func()};
}
func():
push rbp
mov rbp, rsp
mov eax, 2
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
call func()
mov DWORD PTR [rbp-4], eax
mov eax, 0
leave
ret
In [class.temporary]/1.2, the standard says that is it possible to materialize temporaries if the type is "trivially copyable":
1 Temporary objects are created
[...]
—(1.2) when needed by the implementation to pass or return an object of trivially copyable type (see below),
[...]
Question:
- Does implementation like that for fundamental types (int, double, etc.) uses the [class.temporary]/1.2 as source?
- If yes, then does the function call materialize an temporary (using registers) and the return statement initialize that temporary by copy-initialization?
Related
Initialization in return statements of functions that return by-value
Yes.
[class.temporary]/(1.2) is a non-normative reference to [class.temporary]/3, and an implementation can not use it for non-class types, which is the subject of CWG2434: