Limitations
There are two situations in which the
compiler cannot perform inlining. In these cases, it simply reverts to the
ordinary form of a function by taking the inline definition and creating storage
for the function just as it does for a non-inline. If it must do this in
multiple translation units (which would normally cause a multiple definition
error), the linker is told to ignore the multiple definitions.
The compiler cannot perform inlining if
the function is too complicated. This depends upon the particular compiler, but
at the point most compilers give up, the inline probably wouldn’t gain you
any efficiency. In general, any sort of looping is considered too complicated to
expand as an inline, and if you think about it, looping probably entails much
more time inside the function than what is required for the function call
overhead. If the function is just a collection of simple statements, the
compiler probably won’t have any trouble inlining it, but if there are a
lot of statements, the overhead of the function call will be much less than the
cost of executing the body. And remember, every time you call a big inline
function, the entire function body is inserted in place of each call, so you can
easily get code bloat without
any noticeable performance improvement. (Note that some of the examples in this
book may exceed reasonable inline sizes in favor of conserving screen real
estate.)
The compiler also cannot perform inlining
if the address of the function
is taken implicitly or explicitly. If the compiler must produce an address, then
it will allocate storage for the function code and use the resulting address.
However, where an address is not required, the compiler will probably still
inline the code.
It is important to understand that an
inline is just a suggestion to the compiler; the compiler is not forced to
inline anything at all. A good compiler will inline small, simple functions
while intelligently ignoring inlines that are too complicated. This will give
you the results you want – the true semantics of a function call with the
efficiency of a macro.