On 13/02/18 08:00, Juha Nieminen wrote:
>
w...@totalbb.net.tw wrote:
>> The compiled program dosn't indicate sin2 is the same as ::sin
>
> Firstly, 'inline' is a linker instruction, and nowadays has nothing to do
> with actual inlining, as strange as it might sound. (It tells the compiler
> that if the implementation of the function appears in more than one
> compilation unit, ie. more than one object file, for the linker to merge
> them, ie. use only one of them and make everything call that one.)
> It might have affected compiler behavior in terms of actual inlining
> in the distant past, but nowadays most compilers probably just ignore
> it completely when making inlining decisions.
That is a somewhat true, but not entirely accurate. If a non-static
function (or variable, in C++17) is marked "inline" then you can have
more than one definition for the function in different translation units
in the program, but they must all be identical. If the function's
address is taken, you get the same address in all translation units.
It does not mean that the function must be inlined - but many compilers
take it as a strong hint that the function should be inlined, depending
on optimisation levels. It is common not to do any inlining when using
no optimisation, to treat it as a hint when doing some optimisation, and
to ignore it for heavy optimisation (when the compiler does much more
analysis). The gcc attribute "always_inline", however, tells the
compiler to inline the function whenever it is legally possible.
If the compiler does not need a non-inlined version of the function
(because all calls in the current translation unit get inlined, and you
don't take its address), then it does not need to generate the
non-inlined version, even if the function has external linkage.
>
> Secondly, taking the address of an "inline" function will create an
> actual instance of the function, because the address to that function
> has to point somewhere, and it has to be unique. (Although I could be
> talking out of my ass here, since I don't know what the standard says
> about inline functions and taking their addresses.)
AFAIK, you are correct here.
> However, just
> because you took the address of the function, forcing the compiler
> to actually instantiate it, that doesn't stop the compiler from
> still inlining it.
Correct. The compiler can inline some uses of the function while using
a non-inlined version in other cases.
> The implementation of the function could exist
> in the final executable, yet it could have still been inlined
> everywhere where it was called. So execution never actually jumps
> to the function. It's just that when you took the address, it has
> to point somewhere that actually exists. It has to be able to use
> that address (eg. to print it).
>
(I think technically that the compiler does not have to generate a
non-inlined version even if you have taken its address - if the compiler
is sure you never call it via that address, such as in this sample
program. All that is needed then is the program-wide unique address,
not the function implementation. But I think that would take a lot of
sophistication and link-time optimisation to achieve.)