23

This is really bugging me, coming from a C# background.

Sometimes, I see functions written like this:

int computeResult();

This is what I'm used to. But then I see them written like this:

void computeResult(int &result);

I find this strange. What benefits does the second method have over the first, if any? There must be something, since I see it all the time.

jmegaffin
  • 1,162
  • 11
  • 22
  • 2
    This is more of a matter of pragmatism. Sometimes, when the result needs to be in an object, it would require a deep copy onto the stack or allocating a result object on the heap, after which care must be taken to be freed. Using a reference parameter avoids both. – obataku Aug 23 '12 at 01:13
  • 1
    I can see no reason of `void computeResult(int &result);`, unless it is like `bool computeResult(int &result);` – Deqing Aug 23 '12 at 01:21

1 Answers1

22

There are two common reasons for such non-const reference parameters:

  • You may need multiple "out" parameters in a function, and using reference parameter(s) allows for this.

  • Your object may be expensive to copy, and so you pass in a reference that will be mutated rather than returning an object that may get copied as part of the return process. Expensive-to-copy objects may include standard containers (like vector) and objects that manage heap memory where an allocation-copy-deallocate sequence would occur. Note that compilers are getting really good at optimizing away these copies when possible and so this reason has less import than it used to.

EDIT: I should clarify that even in C++ the specific example you've provided with a single builtin type reference parameter is pretty atypical. In such cases a return value is almost always preferred.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • Yes, I can see why doing it with an int is a bit overboard, but it would make sense if I was to be using a string or something? – jmegaffin Aug 23 '12 at 01:23
  • 1
    @Boreal I almost never use this pattern even for strings due to the increased complexity. I let the optimizer do its thing and let the profiler guide my performance changes. – Mark B Aug 23 '12 at 01:25
  • What kind of object would warrant the second pattern? – jmegaffin Aug 23 '12 at 01:26
  • 1
    @Boreal I edited in a couple examples of expensive-to-copy objects. – Mark B Aug 23 '12 at 01:30
  • 2
    Note that the overhead for returning by value is likely to be *very* small, since the copies can be elided or replaced with moves in most cases. – Mankarse Aug 23 '12 at 01:40
  • @MarkB So, if the object is not small (eg, an object with many contents), referencing parameter method will improve performance. Am I right? – Lwin Htoo Ko Aug 23 '12 at 01:46
  • @LwinHtooKo - No, not really. If you already *have* an object the function should modify, passing that by reference is a good idea. If you are creating a new object, the compiler will most often optimize a return by value to avoid copying. – Bo Persson Aug 23 '12 at 06:16
  • @Bo Persson: Is there any reference for your claim about the compiler optimizing it (with actually measured results)? I am really curious, because I have been claiming the same as you in talks with my colleagues, but have never been able to find a good reference – André Aug 23 '12 at 08:13
  • @Andre - No numbers, but we know that modern compilers almost always do this. For example, g++ will optimize return values even at -O0 optimization level. For a good read, also see this article [Want speed? Pass by Value.](http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/) – Bo Persson Aug 23 '12 at 10:03
  • @Bo Persson: Thanks, that's something I was looking for. – André Aug 23 '12 at 11:01
  • 1
    @BoPersson The link died, but it's archived [here](https://web.archive.org/web/20140116234633/http://cpp-next.com:80/archive/2009/08/want-speed-pass-by-value/) - and reviewed somewhat sceptically [here](https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by-value/) – underscore_d Jul 21 '17 at 09:57