5

Explore more and find the answer to determine how to pass in old post (sorry for duplicate)

  • If the function intends to change the argument as a side effect, take it by non-const reference.
  • If the function doesn't modify its argument and the argument is of primitive type, take it by value.
  • Otherwise take it by const reference, except in the following cases
    • If the function would then need to make a copy of the const reference anyway, take it by value.

[Original Post is Below]

I'd like to summarize the use of passing by value, const value, reference, const reference, pointer, const pointer and please correct me and give me your suggestions.

  • As for reference and pointer, use const if possible (thanks to all).
  • There is no performance difference between passing by reference and pointer.
  • When the size is not larger than a pointer (thanks to Mark Ransom), pass by value.

And some questions:

  1. I seldom see passing by const value. Is it useful or the compiler will detect the const-ness in passing by value?
  2. The const reference takes too much space. Can I just use passing by value? Will the modern compilers optimize it to not sacrifice the performance?

According the the article "Want Speed? Pass by Value" juanchopanza mentioned, I add one more item.

  • If you will copy your arguments, pass them by value and let the compiler do the copying other than passing them by const reference and doing the copy by yourself in the function body.

Thanks a lot!

Community
  • 1
  • 1
user1899020
  • 13,167
  • 21
  • 79
  • 154
  • 1
    http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ – juanchopanza Jan 30 '13 at 22:56
  • 5
    Pass by value *if the value is smaller than a pointer*. On a 64-bit system this could be much more than a word. – Mark Ransom Jan 30 '13 at 22:57
  • 6
    Passing by 'const value' is meaningless. It's a copy anyway, so the caller's version can't be modified. – Carl Norum Jan 30 '13 at 22:57
  • 4
    @CarlNorum: But it can be used to catch errors during maintenance. If modifying the value in the function is meaningless but a maintainer modifies it (maybe he though it was a reference) then the compiler can catch that bug and make the maintainer take a second look at what they are doing. Not meaningless, but (I tend to agree with your sentiment) not likely to be useful. – Martin York Jan 30 '13 at 23:02
  • 4
    But why should anyone care what I do internal to a function? I have a hard time understanding why something like that would be proscribed. I guess C++ muddies the water around this stuff a lot. – Carl Norum Jan 30 '13 at 23:03

1 Answers1

4

I seldom see passing by const value. Is it useful or the compiler will detect the const-ness in passing by value?

Passing by const value doesn't really exist. When you pass by value, you can't modify the value in such a way that the changes will be visible outside of the subroutine. This is because when you pass by value, a copy is made of the original value and that copy is used in the function.

The const reference takes too much space. Can I just use passing by value? Will the modern compilers optimize it to not sacrifice the performance?

Passing by (const) reference is not the same as passing by value. When you pass by reference the value is NOT copied, a memory location is simply supplied and thus you may 'modify' (indirectly) the value that you pass by reference.

Take for example, the following:

void byValue(int x) {
    x += 1
}
void byRef(int &x) {
    x += 1
}

// ...
{
    y = 10;
    byValue(y);
    cout << y << endl // Prints 10
    byRef(y);
    cout << y << endl; // Prints 11
}
// ...

Use const as much as possible.

Passing const where necessary is always a good idea. It helps code readability, lets others know what will happen to the values they pass to the method, and helps the compiler catch any mistakes you may make in modifying the value inside the method.

There is no performance difference between passing by reference and pointer.

A negligible amount, if any. The compiler will take care of the details here. It saves you the effort of creating a pointer, and it nicely dereferences it for you.

When the size is not larger than a word, pass by value.

As Mark points out, you do this if the value is smaller than a pointer. Pointers are different sizes on 32bit and 64bit systems (hence the name) and so this is really at your discretion. I'm a fan of passing pointers for nearly everything except the primitive types (char, int8_t, int16_t, float, etc), but that is just my opinion.

Ephemera
  • 8,672
  • 8
  • 44
  • 84