So this seems like a fairly simple question, but I haven't been able to find an answer to it anywhere online. The reason I'm assuming a function which returns a variable is less efficient than a function which takes a variable and changes it is because I think the first would use more memory. However, I could be wrong, I'm not aware of how this affects processing time.

Here's two C++ examples: This a function which returns a variable:

#include <iostream>
short getInput(){
    short input;
    std::cin >> input;
    return input;
}
int main(){
    short input = getInput();
}

You can see in this one that the program needs two input variables to be created, even if the second is only created for a brief amount of time.

This is a function which passes a value by reference:

#include <iostream>
short getInput(short& input){
    std::cin >> input;
}
int main(){
    short input;
    getInput(input);
}

Not only is this example code segment shorter, it only initializes one short variable. Am I wrong on the fact that it's more efficient.

2

There are 2 best solutions below

0
On BEST ANSWER

A value of a small, simple built-in type like short or int is almost certain to be returned in a register, so it won't involve creating anything.

If we simplified your code a tiny bit to something like return 1;, we'd expect the body (when we turned off optimization, so there was still code for anything at all) we'd end up with something like this:

mov rax, 1
ret

If the return value is not small enough to fit in a register, then the compiler is normally going to allocate space in the caller, and pass a hidden reference to that space to the function being called. In other words, it'll do essentially the same thing you're doing manually.

To make a long story short, you should write your code whichever way makes the most sense. If if makes the most sense for your function to return a value, then return a value. If it makes more sense to pass a reference, then do that.

There are a few cases where it makes real sense to modify a referenced variable instead of returning a value though. One is for something like a pop from a stack or a queue. If copying a return value might throw, then there can be a difference in exception safety. For example, you can do something like this:

template <class T>
class queue {
    std::deque<T> data;
public:
    void pop(T &t) { 
        t = data.front();
        data.pop_front();
    }
};

If you attempt to return the T by value, you can end up popping the value off the deque, but then its copy constructor throws when you try to copy the return value.

This way, however, you're only popping the value off the deque if the copy into the "return" value succeeds. If the copy throws, then the value remains on the deque.

0
On

I will attempt an answer, although I'm sure it is probably debatable. I strongly support returning by value instead of using output parameters for the following reasons:

  1. Returning fundamental types by value is extremely efficient. Returning by value also allows "natural" function composition, such as

    double result = sin(exponential(factorial(n)));
    

    Imagine writing this with output parameters for all 3 functions.

  2. Performance begins to matter whenever you return large class objects. However, in that case the compiler can (and does) perform the so called (named) return value optimization. This is an optimization scheme in which the (named) return value is constructed directly into the left hand side object (there are some restrictions, see the link). Furthermore, returning by value plays nicely with C++11 move semantics, so if you have a cheap-to-move object of some type, say Foo, you can write

    my_already_constructed_object = some_function_that_returns_by_value();
    

    and the move assignment operator will do its magic, which is effectively much cheaper than a deep copy (think of it more like a swap).