user12074577
user12074577

Reputation: 1411

call by value vs const call by reference

I am a little confused about the differences between call by value and const call by reference. Could someone please explain this to me. For example, do they both protect against changing the callers argument, are they fast for all object sizes, do either copy the argument while one doesnt, and which use more memory when making a copy?

Upvotes: 3

Views: 8899

Answers (5)

ajhino
ajhino

Reputation: 21

One other point worth mentioning is that call-by-reference functions are converted into inline functions.

Upvotes: 0

Andy Prowl
Andy Prowl

Reputation: 126442

do they both protect against changing the callers argument

Passing by value creates a copy of the argument provided by the caller, so whatever the function does, it does it on a separate objects. This means the original object won't ever be touched, so in this case the answer is "Yes".

Passing by reference to const, on the other hand, lets the function refer the very same object that the caller provided, but it won't let that function modify it... Unless (as correctly remarked by Luchian Grigore in the comments) the function's implementer uses const_cast<> to cast away the const-ness from the reference, which is something that can be safely done only if it is known that the object bound to the reference was not declared to be of a const type (otherwise, you would get Undefined Behavior).

Since this does not seem to be the most likely scenario considering your question, and considering that in general accepting a reference to const represents a promise that the argument won't be touched, then the answer is that as long as we assume this promise to be fulfilled, passing by reference to const won't alter the argument provided by the caller. So the answer is "Yes" again - with the little caveat I mentioned above.

are they fast for all object sizes

No. Although you should first define "fast". If the type of the object being passed is expensive to copy (or to move, if a move is performed rather than a copy), then passing by value might be slow. Passing by reference will always cost you the same (the size of an address), no matter what is the type of the value you are passing.

Notice, that on some architecture and for some data types (like char) passing by value could be faster than passing by reference, while the opposite is generally true for large enough UDTs.

and which use more memory when making a copy?

Since only one of them is causing a copy, the question has an obvious answer.

Upvotes: 7

Zdeslav Vojkovic
Zdeslav Vojkovic

Reputation: 14591

I suppose that you mean the difference between:

void Fn1(MyType x);

and

void Fn2(const MyType& x);

In former case, a copy of the object is always created, which makes it slower especially if the type has a non-trivial constructor. The original object will be unaffected by any changes done on the copy within the function, but the copy itself can be changed.

The latter example will not create a copy and will in general be faster. Inside the function, only the const functions can be called on the argument (unless you resort to dirty tricks like casting away constness), thus guaranteeing that the object will not be modified.

IMPORTANT: This discussion doesn't cover types with special semantics, like smart pointers. In that case, call by value will still allow you to change what is logically the same object, i.e. not the smart ptr instance itself but the object it points to.

So here are the answers to your questions:

  • do they both protect against changing the callers argument: yes, the original object will remain unchanged (excluding tricks)
  • are they fast for all object sizes: they are not equally fast - call by reference is in general faster, except for some primitive types where speed is more or less the same or maybe even marginally faster, depending on compiler optimizations.
  • do either copy the argument while one doesnt: call by value creates a copy, call by reference doesn't
  • which use more memory when making a copy? call by reference doesn't create a copy so the answer is clear

Upvotes: 0

idoo
idoo

Reputation: 330

call by value will copy all the elements of the object it does protect the callers argument because if you are going to change something it is only a copy you are changing.
calling by const reference does not copy elements but because of the "const" it will protect caller's argument.

You const reference.

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258618

The main difference is that passing by const reference (or non-const) doesn't make a copy of the argument. (the copy is actually subject to copy elision, but theoretically it's a copy that's passed to the function when you pass by value)

In some cases, passing by value is just as fast, or even faster (typically when the object is at most the size of a register). You'd usually pass basic types by value, and class-types by reference.

When passing by const reference you can still modify the original value just by casting the const away (via const_cast), but that results in undefined behavior if the original value is const.

Upvotes: 0

Related Questions