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

家住魔仙堡 提交于 2021-02-18 20:08:48

问题


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?


回答1:


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




回答2:


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.




回答3:


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.




回答4:


This is MSVC2010 64bit compiler, full optimizations:

int foo( int i )
{
 int a = i + i;

 return ( a );
}
//Disassembly:
//00000001`3ff11c50 8d0409          lea     eax,[rcx+rcx]
//00000001`3ff11c53 c3              ret

int bar( int const & i )
{
 int a = i + i;

 return ( a );
}
//Disassembly:
//00000001`3ff11c10 8b01            mov     eax,dword ptr [rcx]
//00000001`3ff11c12 03c0            add     eax,eax
//00000001`3ff11c14 c3              ret

In the first case, value is passed on RCX, in the second - address passed on RCX. Of course, if functions are inlined, as Ben said, then the produced code might be absolutely the same in both cases.

Passing instances of "small" classes (say, class only has an int data member and trivial constructor, bitwise copy-constructor etc) is faster by value. Compiler will optimize it as, essentially, just passing a copy of int. So, you can overload your function, as Wyzard pointed out, using some type traits. Something like that:

template< typename PType >
PType Func( typename std::enable_if< ( sizeof( PType ) > sizeof( size_t ) ), PType const & >::type f )
{
 //large things: reference
}

template< typename PType >
PType Func( typename std::enable_if< ( sizeof( PType ) <= sizeof( size_t ) ), PType  >::type f )
{
 //small things: value
}


来源:https://stackoverflow.com/questions/9014021/will-a-good-c-compiler-optimize-a-reference-away

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!