2

I recently decided to unclutter a header file which had a lot of definitions like so:

// api.h
template< typename T>
inline void func( T param )
{
    // stuff here
}

so I thought of turning it into:

// api.h
#include "api_details.h"
template< typename T>
inline void func( T param )
{
    return details::func( param );
}

// api_details.h
namespace details {
    template< typename T>
    inline void func( T param )
    {
        // stuff here
    }
}

hoping that inline wouldn't add a cost to the extra copy I'm performing.

although the answers in 'C++ do inline functions prevent copying?' seem to imply that no copying takes place, this question arises:

if inlining doesn't copy the function parameters, then wouldn't the following behave badly?

inline void change_value( int i ) {
    i++;
}

...
int x=5;
change_value(x);
assert(x==5);

is it just the optimizer that decides where to copy or not, or does the standard say anything about that?

Community
  • 1
  • 1
Grim Fandango
  • 2,296
  • 1
  • 19
  • 27
  • Note: Declaring a template function inline is redundant. – Aleph Apr 25 '13 at 16:47
  • @AnotherTest really? I was just under the assumption that it would only be produced if a relevant call were made, not that it would be produced inline. But declaring inline anything is of course not a hard and fast guarantee at all, so maybe that's why? – im so confused Apr 25 '13 at 16:50
  • 2
    The semantics of the call must be maintained when a function is inlined. Which is to say that modifications to a "by value" parameter will not be reflected back in the "caller". – Hot Licks Apr 25 '13 at 16:50
  • @AK4749 as far as I know, template functions are automatically inline (although that might not imply inlined). – Aleph Apr 25 '13 at 16:52
  • the compiler is never allowed to change _observable_ behaviour. – stefan Apr 25 '13 at 17:01
  • 1
    @stefan In general, no, compilers cannot change observable behavior (this is called the "as is" rule). The main exception, however, is to allow for reducing the number of temporaries being copied and destroyed, e.g., for parameters and return values. Basically, the standard describes the rules that create copies of objects, but also allows for needless copies to be optimized away (even when copying has side-effects). This is the one notable exception to the "as is" rule. If your object copying or destruction has side-effects, optimization might change the observable behavior. – Mikael Persson Apr 25 '13 at 18:47

1 Answers1

11

if inlining doesn't copy the function parameters, then wouldn't the following behave badly?

In case if you change parameter it will be copied. And it is unrelated on function being inline or not.

is it just the optimizer that decides where to copy or not, or does the standard say anything about that?

Yes this is optimizer's task. Standard mentions only behaviour, not implementation(there some references regarding to implementation, but only few of them). And inline itself doesn't guarantee that function will be inlined, and vice versa, optimizer may inilne functions that wasn't declared as inline.
What really matters is that parameters that was passed by value will not be changed by function call. No matter declared it inline or not, and no matter it is actually being inlined or not.
Given that nowadays compilers are often much smarter on optimization that people are, inline usually means not "inline this function" but rather "this function may have multiply(but still identical!) definitions across translation units".

alexrider
  • 4,449
  • 1
  • 17
  • 27