Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the object returned from a function still created when it is not used?

Tags:

c++

lifetime

Consider the following code. What happens when doStuff() is called but the return value is not used? Is SomeClass still created? Of course the creation itself can have important side effects, but so can copy-constructors and they are still omitted in RVO / copy-elision.

SomeClass doStuff(){
    //...do stuff
    return SomeClass( /**/);
}

SomeClass some_object = doStuff();
doStuff(); //What happens here?

(Edit: tested this with GCC -O3. The object is constructed and then destructed right away)

like image 988
AdyAdy Avatar asked Feb 14 '18 08:02

AdyAdy


People also ask

What is meant by returning an object from a method?

Returning a Value from a MethodJava requires that a method declare the data type of the value that it returns. If a method does not return a value, it must be declared to return void . Methods can return either values of primitive data types or of reference data types.

Can functions return any type of object?

A function may be defined to return any type of value, except an array type or a function type; these exclusions must be handled by returning a pointer to the array or function. When a function does not return a value, void is the type specifier in the function declaration and definition.

Is function an object?

In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects. For more examples and explanations, see the JavaScript guide about functions.

Can reference to an object be returned?

Explanation: This is possible but not always, since the reference being returned may get destroyed with the return of method. This is an undesirable condition, hence it is not always possible to return references. But it is always possible if the referred element is not local to the method.


2 Answers

I feel there's a misunderstanding when it comes to RVO and copy elision. It doesn't mean that a function's return value is not created. It's always created, that's not something an implementation can cop out of doing.

The only leeway, when it comes to eliding copies, despite side effects, is with cutting the middle man. When you initialize an object with the result of the call, then the standard allows plugging the target object in, for the function to initialize directly.

If you don't provide a target object (by using the result), then a temporary must be materialized, and destroyed, as part of the full expression that contains the function call.

So to play a bit with your example:

doStuff(); // An object is created and destroyed as part of temporary materialization
           // Depending on the compilers analysis under the as-if rule, there may be
           // further optimization which gets rid of it all. But there is an object there 
           // formally.

std::rand() && (doStuff(), std::rand());
// Depending on the result of std::rand(), this may or may not create an object.
// If the left sub-expression evaluates to a falsy value, no result object is materialized.
// Otherwise, one is materialized before the second call to std::rand() and 
// destroyed after it.
like image 187
StoryTeller - Unslander Monica Avatar answered Oct 01 '22 09:10

StoryTeller - Unslander Monica


A compiler may elide an unnecessary copy in certain cases, even if it has side effects, yes.

A compiler may not elide an object's entire existence, if it has side effects.

If it doesn't have side effects then no result is observable so whether the existence happened or not is effectively a non-question.

tl;dr: the standard lists very specific elision opportunities, and this is not one of them.

like image 39
Lightness Races in Orbit Avatar answered Oct 01 '22 11:10

Lightness Races in Orbit