I am coming from Java where anything is reference, so I am trying to figure out the basic of c++ instance creations.
Employee getEmp(int a) {
Employee local(a);
return local;
}
Employee myEmp = m.getEmp(10);
Is it correct that there are 3 times Employee instantiation (without RVO)?
1 – Create a local copy
2 – Temporary is created for binding to the reference)
3 – create myEmp
Why there is need in step 2? Why doesn’t copy the local directly to myEmp?
If I am going to use only Ubuntu should I count on RVO and am I correct that with RVO only two instance creation is done (no need in step 2)?
Thank you!!!
The semantics for function return are defined independantly of what you
do with the return value: the returned value is copied somewhere where
it won’t disappear when the local stack frame is destructed. So without
RVO, in your example, you have:
Construction of a local variable, named
local, in the stack frameof
getEmp.Copy construction of the returned object somewhere which the caller
will be able to access. Typically, the caller allocates memory for the
returned object in its own stack frame, and passes a hidden argument
with the address of this memory to the called function. RVO or NRVO
allow the compiler to “alias” this returned object to a local object: in
your case, to create the variable
localat the address passed in as ahidden argument, rather than in the local stack frame.
After return, the returned object will be “used”, then destructed at
the end of the full expression. If this use is to initialize a local
variable using the copy constructor, the intermediate value may be
elided; the compiler will pass the address of the actual object to be
constructed as hidden argument to the called function. (Strictly
speaking, this is not NRVO, but it is related.) Other uses, however,
cannot be elided; if the returned value is used in an assignment to an
existing variable, for example, the assignment operator will require a
reference to the instance to be assigned. The formal requirement for
the intermediate object is there because most uses of return values are
not as an argument to the copy constructor.
Finally, given modern compiler technology, you can probably count on the
compiler systematically eliding the second copy above. The first copy
(RVO or NRVO) may be somewhat more difficult. I would expect to see it
systematically in simple cases like the above: RVO anytime there is a
single return of a temporary, and NRVO anytime there is a single return
which returns a named variable defined at the outermost scope of the
function. NRVO (and in practice RVO as well, although I don’t know why)
is less likely to occur if there are several returns in the function.