Reputation: 235
Consider the following function:
template <class T, class Priority>
void MutableQueue<T, Priority>::update(const T& item, const Priority& priority)
{
...
}
Would modern x86-64 compilers be smart enough to pass the priority argument by value rather than reference if the priority type could fit within a register?
Upvotes: 8
Views: 875
Reputation: 3769
As @black mentioned, optimizations are compiler and platform dependent. That said, we typically expect a number of optimizations to happen day-to-day when using a good optimizing compiler. For instance, we count on function inlining, register allocation, converting constant multiplications and divisions to bit-shifts when possible, etc.
To answer your question
Would modern x86-64 compilers be smart enough to pass the priority argument by value rather than reference if the priority type could fit within a register?
I'll simply try it out. See for your self:
This is the code:
template<typename T>
T square(const T& num) {
return num * num;
}
int sq(int x) {
return square(x);
}
GCC -O3
, -O2
, and -O1
reliably perform this optimization.
Clang 3.5.1, on the other hand, does not seem to perform this optimization.
Should you count on such optimization happening? Not always, and not absolutely--the C++ standard says nothing about when an optimization like this could take place. In practice, if you are using GCC, you can 'expect' the optimization to take place.
If you absolutely positively want to ensure that such optimization happens, you will want to use template specialization.
Upvotes: 3
Reputation: 217283
Compiler may do the optimization, but it is not mandatory.
To force to pass the "best" type, you may use boost: http://www.boost.org/doc/libs/1_55_0/libs/utility/call_traits.htm
Replacing const T&
(where passing by value is correct) by call_traits<T>::param_type
.
So your code may become:
template <class T, class Priority>
void MutableQueue<T, Priority>::update(call_traits<T>::param_type item,
call_traits<Priority>::param_type priority)
{
...
}
Upvotes: 3
Reputation: 8494
This is totally platform and compiler dependent and so is how the arguments are passed to a function.
These specifics are defined in the ABI of the system the program runs on; some have a large number of registers and therefore use them mainly. Some push them all on the stack. Some mix them together up to N-th parameter.
Again, it is something you cannot rely on; you can check it in a couple of ways, though. The C++ language has no concept of a register.
Upvotes: 0