Reputation: 7663
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:
Upvotes: 0
Views: 90
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
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
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