15

In C++, is there an efficiency benefit in passing primitive types by reference instead of returning by value?

TRiG
  • 10,148
  • 7
  • 57
  • 107
user997112
  • 29,025
  • 43
  • 182
  • 361
  • 1
    Probably not, but ultimately you have to profile your particular situation to really know. – Vaughn Cato Jun 16 '13 at 13:38
  • possible duplicate of [How to pass objects to functions in C++?](http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c) – awesoon Jun 16 '13 at 13:39
  • @soon primitive types != objects. – djechlin Jun 16 '13 at 13:39
  • 1
    @djechlin, Did you read the answers in the link I posted below? – awesoon Jun 16 '13 at 13:40
  • 1
    @djechlin instances of primitive types == objects. – juanchopanza Jun 16 '13 at 13:43
  • @soon no, I read your comment that said "possible duplicate of How to pass objects to functions in C++?" Please leave a more informative explanation, e.g. link to the relevant answer. – djechlin Jun 16 '13 at 13:47
  • @juanchopanza I'm used to the nomenclature in which an object is an instance of a class, but perhaps you're referring to a different technical definition, and OP of proposed dupe seems to have meant instance of class. – djechlin Jun 16 '13 at 13:51
  • @djechlin, It's just auto-comment. You could read first two answers from the question - both says, using pass-by-value is prefer for primitive types. – awesoon Jun 16 '13 at 13:57
  • @soon I know it's an autocomment. In many cases autocomment is sufficient to explain why it's a duplicate. In this case it's not. Therefore you should leave a more informative *manual* comment in these cases. If you post manually before closing the autocomment will not appear. – djechlin Jun 16 '13 at 14:01
  • Anyway that question is not about efficiency, so leaving this open. – djechlin Jun 16 '13 at 14:02
  • [Also relevant](http://stackoverflow.com/questions/15600499/how-to-pass-parameters-correctly/15600615#15600615) – Andy Prowl Jun 16 '13 at 14:04
  • possible duplicate of [how to "return an object" in C++](http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c) – rubenvb Jun 16 '13 at 14:28
  • 1
    This might be relevant : http://en.wikipedia.org/wiki/Return_value_optimization – SylvainD Jun 16 '13 at 17:09

3 Answers3

8

[...] is there an efficiency benefit to passing primitive types by reference instead of returning by value?

Unlikely. First of all, unless you have data from your profiler that give you a reason for doing otherwise, you should not worry about performance issues when designing your program. Choose the simplest design, and the design that best communicates your intent.

Moreover, primitive types are usually cheap to copy, so this is unlikely to be the bottleneck in your application. And since it is the simplest option and the one that makes the interface of the function clearest, you should pass by value.

Just looking at the signature, it is clear that a function such as:

void foo(int);

Will not store a reference to the argument (and consequently, won't run into issues such as dangling references or pointers), will not alter the argument in a way that is visible to the caller, and so on and so on.

None of the above can be deduced from a function signature like:

void f(int&); // May modify the argument! Will it? Who knows...

Or even:

void f(int const&); // May store a reference! Will it? Who knows...

Besides, passing by value may even improve performance by allowing the compiler to perform optimizations that potential aliasing would prevent.

Of course, all of this is under the assumption that you do not actually need to modify the argument inside the function in a way that side-effects on that argument will be visible to the caller after the function returns - or store a reference to that argument.

If that is the case, then you should of course pass by reference and use the appropriate const qualification.

For a broader discussion, also see this Q&A on StackOverflow.

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
4

In general there won't be any performance benefit and there may well be a performance cost. Consider this code:

void foo(const int& a, const int& b, int& res) {
    res = a + b;
    res *= a;
}

int a = 1, b = 2;
foo(a, b, a);

When a compiler encounters a function like add() it must assume that a and res may alias as in the example call so without global optimizations it will have to generate code that loads a, loads b, then stores the result of a + b to res, then loads a again and performs a multiply, before storing the result back to res.

If instead you'd written your function like this:

int foo(int a, int b) {
    int res = a + b;
    res *= a;
    return res;
}

int a = 1, b = 2;
int c = foo(a, b);

Then the compiler can load a and b into registers (or even pass them directly in registers), do the add and multiply in registers and then return the result (which in many calling conventions can be returned directly in the register it was generated in).

In most cases you actually want the semantics in the pass / return by value version of foo and the aliasing semantics possible in the pass / return by reference version do not really need to be supported. You can end up paying a real performance penalty by using the pass / return by reference version.

Chandler Carruth gave a good talk that touched on this at C++ Now.

mattnewport
  • 13,728
  • 2
  • 35
  • 39
1

There may be some obscure architecture where this is the case, but I'm not aware of any where returning builtin types is less performant than passing an out parameter by reference. You can always examine the relevant assembly to compare if you want.

Mark B
  • 95,107
  • 10
  • 109
  • 188