Germán Diago
Germán Diago

Reputation: 7663

Difference from compiler perspective between passing by const value or const ref

In the context of c++.

I wonder what is the difference, between this:

T f(T const val);

and this:

T f(T const & val);

I do know one is a pass by value, but, from the compiler's pespective, this is a value that is not going to change, so my questions are:

  1. Is the compiler still required to make a copy in the case of the const value parameter passing?
  2. Which one is better for the optimizer of the compiler and why?

Upvotes: 0

Views: 90

Answers (3)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145204

Regarding

Is the compiler still required to make a copy in the case of the const value parameter passing?

Yes, the program must behave as if a copy is made.

In practice an address may be passed, and the function may then itself make a copy where or if that turns out to be necessary (because of calls to other functions).

Note that a top-level const on a formal argument is disregarded for the function type; it only affects the implementation of the function, if it’s present in the implementation’s function head.

Which one is better for the optimizer of the compiler and why?

It depends very much on the type, on the machine code inlining, on whether that value is going to be stored somewhere to be accessible after the call, and on whether whole program optimization is used. In short, it depends. As a general rule, measure if you think there might be an efficiency issue.

Upvotes: 0

Mats Petersson
Mats Petersson

Reputation: 129314

Example 1:

T f(T const val);

If the compiler can't inline (or otherwise do stuff to modify the function f), it must make a copy of T and pass it to f. The const makes no difference from the perspective of the calling code, only inside the function f.

Example 2:

T f(T const & val);

The compiler passes the address of val to the function, and thus doesn't need to make a copy.

However, using reference for small/simple types will lead to extra overhead, since the argument is passed as the address of the element, and the contents of f will have to make extra operations to load the address then load the actual content of val. So it's a matter of "how complicated is it to copy T and how complicated is the function f's use of val" that determines which will be most efficient. Always, if you are trying to get better performance, measure the results!

Finally, if the compiler is able to inline the code, it may well eliminate all copies of an object (assuming constructor is known and doesn't prevent being eliminated - adding I/O to the constructor for example will prevent it from being eliminated).

Upvotes: 1

erenon
erenon

Reputation: 19118

Assume the following:

launch_service(const Configuration); // launches service in a different thread

Configuration config;

launch_service(config);
config.set("key", "value");

If Configuration is taken by reference, the service running in a separate thread might read the later added configuration setting key. If it's taken by value (like in the example), later changes made by other threads cannot be reflected.

Which means, taking something const value or const ref is different, and the compiler has to create a copy in the former.

Upvotes: 1

Related Questions