Pass By Value, Pass By Reference

Started by
1 comment, last by Antheus 13 years, 9 months ago
Hi all,

Been learning C++ for a while now but I'm still confused as to when I should pass-by-value and when I should use pass-by-reference. Googling this problem yields the following information:

- Pass-by-value creates a copy of the variable which takes up extra memory and has a processing overhead. HOWEVER, compiler may optimise to pass-by-reference where appropriate but you shouldn't count on it.

So it seems clear that pass-by-reference, or better yet, const reference is the way to go in most cases but...

- Some sources say passing-by-reference still has the overhead of constructing and passing a pointer like value which points to the data being referenced, so for types smaller than / same size as* a pointer pass-by-value is quicker.

- Other sources say that the above is in fact wrong and that most compilers have special optimisations for passing integral types and only those should be pass-by-value and everything else should be pass-by-reference.

*( sources vary on which is faster/better in the case of the same size )

I realise which you should use is also dependent on the scenario in which it is used. So here is a context:

ADTClass myADT;MyType myVar = <some valid initialisation>;if( MyFunction() ){    myADT.m_val = myVar;}else{    myADT.m_otherVal = myVar;}


K, I'm happy here since myVar gets copied directly to the target location ( I think ). Now:

ADTClass myADT;
MyType myVar = <some valid initialisation>;
myADT.SetOneOfMyVars( myVar );

Where SetOneOfMyVars like this:

void ADTClass::SetOneOfMyVars( MyType myVar ) {    if( MyFunction() )    {        m_val = myVar;    }    else    {        m_otherVal = myVar;    }}


Or like this:

void ADTClass::SetOneOfMyVars( const MyType& myVar ) {    if( MyFunction() )    {        m_val = myVar;    }    else    {        m_otherVal = myVar;    }}

And MyType is any type from an int to an 128 byte class.

Which one is faster? Does it depend on the compiler? The size of MyType? Whether MyType is an integral type? How does it get affected if SetOneOfMyVars is inlined / cannot be inlined?

Getting very confused about exactly what happens behind the scenes when you pass something to a function!
Advertisement
Quote:Original post by mjand
Ask yourself two questions.

1)How hard is it to change my program between passing by value and passing by reference?

2)If I had a way to tell where my program was slowest and it said a function that used pass by value or pass by reference was slow, how hard would it be to try the other way to see if it was faster?

In my opinion the answer in both caes is "not hard at all". And there are tools that can show you where your program is slowest. These tools are called profilers. See, for small objects the difference in speed between pass by value and reference is going to be negligible in most situations so worrying about the speed without knowing whether it's going to be an actual bottleneck isn't that big of a concern of yours. In some cases it can be incredibly difficult to just look at your code and be able to tell what will be faster.

That said, by default I keep built-in types as pass by value and all user-defined types as pass by reference. Better to be consistent and you never know if you're user-defined type will someday increase in size.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Quote:Original post by mjand

*( sources vary on which is faster/better in the case of the same size )

Because it depends on compiler, platform and perhaps some other constraints.

Quote:Getting very confused about exactly what happens behind the scenes when you pass something to a function!

It depends on compiler, calling convention, the type, optimizations, and probably a few more factors.

This topic is closed to new replies.

Advertisement