Passing const references of primitive types as arguments to a function

Consider the following function:

template <class T, class Priority> void MutableQueue<T, Priority>::update(const T& item, const Priority& priority) { ... } 

Can modern x86-64 compilers be smart enough to pass a priority argument by value, rather than a link, if the priority type can fit in a register?

+6
source share
3 answers

As mentioned in @black, optimization is compiler and platform dependent. However, we usually expect a series of optimizations to occur day by day using a good optimizing compiler. For example, we expect to include functions, register allocation, conversion of constant multiplications and divisions to bit shifts, when possible, etc.

To answer your question

Can modern x86-64 compilers be smart enough to pass a priority argument by value, rather than a link, if the priority type can fit in a register?

I will just try it. See for yourself:

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 such an optimization be counted on? Not always, but not quite - the C ++ standard does not say anything about when such an optimization can happen. In practice, if you use GCC, you can "expect" optimization.

If you are absolutely sure that such optimization will happen, you will want to use the specialization of the template .

+2
source

The compiler can perform optimizations, but this is optional.

To make the "better" type pass, you can use boost: http://www.boost.org/doc/libs/1_55_0/libs/utility/call_traits.htm

Replacing const T& (where the transmission is at the correct value) with call_traits<T>::param_type .

So your code could become:

 template <class T, class Priority> void MutableQueue<T, Priority>::update(call_traits<T>::param_type item, call_traits<Priority>::param_type priority) { ... } 
+2
source

This is completely platform and compiler dependent, and so arguments are passed to the function.
These features are defined in the ABI system in which the program runs; some of them have a large number of registers and therefore use them mainly. Some push them all onto the stack. Some mix them with the Nth parameter.

Again, on what you cannot rely on; You can check this in several ways. C ++ does not have a case for case.

0
source

Source: https://habr.com/ru/post/986419/


All Articles