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.
A value of a small, simple built-in type like
short
orint
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: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: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.