(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:
Related
Initialization in return statements of functions that return by-value
Does an implementation that returns fundamental types by value using registers do "temporary materialization"?
Yes.
Does implementation like that for fundamental types (int, double, etc.) uses the [class.temporary]/1.2 as source?
[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:
2434. Mandatory copy elision vs non-class objects
In the following example,
int f() { X x; return 4; } int a = f();
a
must be directly initialized in the return statement off()
because the exception permitting temporaries for function arguments and return types in [class.temporary] paragraph 3 applies only to certain class types.This requirement is observable, since the destructor of
X
in the example could inspect the value ofa
.The permissions in this paragraph should also apply to all non-class types.