C++ Pass by value or const reference. Which is better?

Started by
9 comments, last by Rebooted 17 years, 11 months ago
I'm thinking only about built in types in C++ here. If a function needs to be passed an integer is it better to pass that integer by value or by a const reference? For the built in types does it really matter? Thanks.
Advertisement
It depends on what you are doing with that value. If you aren't going to manipulate it any way, passing by const reference is probably the better way to go. If you want to be able to change the value (kind of like as a return value), you can just pass by reference. If you want to be able to play with the value passed but not affect the original source, pass by value. Passing by value does create a seperate copy of the variable, so there might be a little overhead, but for most of the builtin types, it should be fairly negligible.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

When you say "built in types" I can only assume you mean primitives. Primitives are the values such as int, double, bool... the ones that aren't necessarily objects. Primitives are always stored on the stack except in the case that you make a pointer to an int. In which case the pointer is stored on the heap (where most objects go) and you would normally dereference the pointer in order to access the original int. It basically comes down to the size of the object you're passing. When you pass a reference, it is only one 'word' (4 bytes on a 32bit arch). When you pass an int you are also passing 4 bytes on a 32bit architecture. So there really isn't a difference. On the other hand, if you pass a double (which is 8 bytes on 32bit arch) then it is probably more efficient to just pass a reference.

i'm rusty at C++ so I could be wrong on any of these issues but the main idea should be there.
For small built-in types it is probably LESS overhead to pass by value since then the variable can be manipulated directly off the stack without the additional level of indirection a reference would entail.

There is certainly no more overhead by value in these cases since if the value is not pushed onto the stack, the address of the variable being referenced would have to be instead.

To be honest though, a modern compiler would probably optimise these differences away so I wouldn't worry about it. I only tend to pass by const value for large objects that require significant copying.

Paul
Since everybody seems to feel the difference is negligible, I'd like to add that in those cases, I pick the construct that best represents what I aim to do with it.

For instance, a struct implies "naked collection of data", whereas classes typically imply OO and self-management. Both would work equally well as a composite data store, but the connotations are different.
XBox 360 gamertag: templewulf feel free to add me!
Quote:Original post by templewulf
Since everybody seems to feel the difference is negligible, I'd like to add that in those cases, I pick the construct that best represents what I aim to do with it.

For instance, a struct implies "naked collection of data", whereas classes typically imply OO and self-management. Both would work equally well as a composite data store, but the connotations are different.


How is this related to the question?
The answer to this depends on if you want to change the value of the original and the size of the object you are passing.

If you have a large class then you norammly pass by ref so that you do not have to copy the large class. If you need to change the original then you norammly pass by reference. If it is a primative or very small class or struct then you can pass by value.


theTroll
Quote:Original post by rick_appleton
Quote:Original post by templewulf
Since everybody seems to feel the difference is negligible, I'd like to add that in those cases, I pick the construct that best represents what I aim to do with it.

For instance, a struct implies "naked collection of data", whereas classes typically imply OO and self-management. Both would work equally well as a composite data store, but the connotations are different.


How is this related to the question?


As an analog in how someone might use different constructs in situations that render their differences negligible.
XBox 360 gamertag: templewulf feel free to add me!
Basically, the tradeoff is complexity vs. performance.

To reduce complexity, you should pass by value. However, an effective way to improve performance is to pass by reference those types that don't fit in a register and/or are expensive to copy.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by Eugenek

I'm thinking only about built in types in C++ here. If a function needs to be passed an integer is it better to pass that integer by value or by a const reference? For the built in types does it really matter?

Thanks.


What in the world are all you people above responding to. REREAD the original question. It specifically asks about integer, and passing built in types by value or by CONST reference.

In other words, the OP is not asking about custom types, the op is not asking about modifying the value (they understand const reference). They are asking 1 very simple specific question, the best way to pass built-in data that does not need to be modified to a function.

The answer is - by value. Period. It is not, nor has it ever been debatable. Pointers themselves are one of these "built-in" types, and I cannot imaging wanting to pass pointers, ints, bools, shorts, floats ... by const reference - its paying a small but very significant runtime cost for absolutely no gain, in any possible situation:

Looking at the following code, you can see a case where a primative type would be passed by const reference ... not because it is better or more efficient, but because the typedefs might exist in order that the actual type of the object may be hidden from the client, and therefore might be a class or some other type (such as when writting a templated class).

// some library header
typedef void* PointerType;
typedef int IntegralType;

// some client
void Foo(const PointerType &myVal);
void Foo(const IntegralType &myVal);

//OR

template <typename T>
void DoStuff(Sink &sink, const T &val)
{
sink.Process(val);
}

but you would NEVER write code like this:

void Foo(const int& myVal);

The difference is, in the first cases you might not known 100% for all time the exact types being used, and in the interest of flexibility you choose the const reference version. In the later case you know the type 100% completely at the line of code in question and have no reason to do silly roundabout things with values when the langauge is made to pass primatives by value efficiently. This is one of the primary performance improvements in using a langauge like C / C++ over langauges where everything is derived from an object base class or is always a reference in the first place.

Good Luck.

This topic is closed to new replies.

Advertisement