TITLE: value semantics and temporary lifetimes (Newsgroups: comp.lang.c++.moderated, 11 Jun 97) HOWARD: Walt Howard > > I have a need to know exactly how return values are returned > to a caller and when this happens in relation to destructors > being called. CLAMAGE: stephen.clamage@eng.sun.com Implementations have considerable lattitude in how values are returned from functions, and in particular in how many temporary copies are involved. The implementation doesn't have to be consistent and doesn't have to tell you what it will do. You should never write code whose correctness depends on whether, or on how many, temps get created and destroyed. HOWARD: > I am assuming that destructors get called AFTER return values > are copied to wherever they are going. CLAMAGE: Depending on what you mean, that might not be a safe assumption. Example: T foo() { T t; ... return t; // return by value } void bar() { T u; ... u = foo(); // assign value to u The logical semantics for this code are that a temp copy of foo's t is constructed, t is destroyed, then the temp is assigned to bar's u, then the temp is destroyed. Thus, t will be destroyed before u gets its value. But if you wrote T u = foo(); // initialize u with value the temp can be eliminated (but might not be). If the temp is eliminated, u is copy-constructed with the value of t, and then t is destroyed. Thus, subtle differences in how you write the code as well as optimizations the compiler chooses to make can affect the details of creation and destruction of temps. If the correctness of the code depends on whether a temp is involved, you might want to consider passing in a reference argument and not returning a value. Two examples: void foo(T& returnval) { ... ; returnval = something; } T& foo(T& returnval) { ... ; return returnval; }