Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will a good C++ compiler optimize a reference away?

I want to write a template function that does something with a std::stack<T> and an instance of T, e.g.:

template<class StackType> inline
bool some_func( StackType const &s, typename StackType::value_type const &v ) {
  // ...
}

The reason I pass v by reference is of course to optimize for the case where StackType::value_type is a struct or class and not copy an entire object by value.

However, if StackType::value_type is a "simple" type like int, then it's of course better simply to pass it by value.

The question is: for a type such as int that would become int const& as a formal argument in the above function, will the compiler optimize away the reference and simply pass it by value?

like image 838
Paul J. Lucas Avatar asked Jan 26 '12 04:01

Paul J. Lucas


People also ask

Do compilers optimize for loops?

The source code compiler performs only minor optimizations. For example, it doesn't perform function inlining and loop optimizations.

What is compiler optimization in C?

Compiler optimization is generally implemented using a sequence of optimizing transformations, algorithms which take a program and transform it to produce a semantically equivalent output program that uses fewer resources or executes faster.

Do compilers Optimise code?

Compilers are free to optimize code so long as they can guarantee the semantics of the code are not changed.


3 Answers

I look in gcc optimization options here http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

And actually there is an option for your case:

-fipa-sra

Perform interprocedural scalar replacement of aggregates, removal of unused parameters and replacement of parameters passed by reference by parameters passed by value.

Enabled at levels -O2, -O3 and -Os

As far as I know, -O2 is usual option for release build on linux.

So, the short answer is: one of good compiler does

like image 141
Alexandr Priymak Avatar answered Oct 14 '22 18:10

Alexandr Priymak


Though I haven't actually tested any compilers for this, I doubt it. You're assuming that passing a const reference is indistinguishable from just passing a value, but that's not true, and the compiler shouldn't assume that it is.

Since the reference is const, your function can't modify the value through it, but other parts of the code may have access to the original (non-const) variable, and might modify it. Your function might call some other function which changes it, for example, or there might be another thread running concurrently that does it.

If something else modifies that original variable, your function, with its reference, should see the new value. If the compiler replaced the reference with a copy, the function would still see the old value.

You might be interested in Boost's call traits library, though. It provides a template type call_traits<T>::param_type which is a const reference for "big" types that you don't want to copy, and a value for "small" types where a copy would be more efficient. Basically, what you're wanting the compiler to do implicitly, you can do explicitly with your code.

like image 21
Wyzard Avatar answered Oct 14 '22 17:10

Wyzard


Whenever the compiler is able to inline, the resulting cross-procedural optimization will eliminate the expense of finding and passing an address.

For non-inline-able function calls, the reference probably will be implemented as a pointer, not pass-by-value.

like image 41
Ben Voigt Avatar answered Oct 14 '22 18:10

Ben Voigt