Re: Ways to make inline work?
On Aug 3, 9:37 am, "Alf P. Steinbach" <al...@start.no> wrote:
* Barry:
"inline" allows you to define a given function with extern linkage, in
more than one compilation unit. In practice that's done by placing the
function definition in a header file, and that's also the practical
value, being able to define functions in header files (this was before
templates were introduced: templates provide a slightly more powerful
mechanism for the same, applying also to data). The mnemonic value of
that keyword is that the function's code is "inline" in the header file.
That's not really what the standard says. The standard
explicitly says "The inline specifier indicates to the
implementation that inline substitution of the function body at
the point of call is to be preferred to the usual function call
mechanism." Of course "to be preferred" is definitly not what
could be considered normative; the strictly normative effect is
to allow the function to be defined in more than one translation
unit. But a compiler which ignores the clearly stated intent of
the standard, without good reason, cannot be considered a good
compiler.
And templates, of course, have a completely different role; a
template function is not implicitly inline, and an inline
function is not a template.
"inline" can be placed on a pure declaration or a definition.
A function declared (or defined) as "inline" must be defined
in all compilation units where it's used, and essentially it
must be defined in exactly the same way except for whitespace
-- which is no problem when the definition is provided by a
reasonable header file.
Whitespace or comments (which are a form of whitespace, of
course). After preprocessing, of course. (The exact rules say
that the token sequence must be identical.) In addition, almost
all names must bind identically. (There is an exception for
constant data.) Something like:
inline T
f() { return 0 ; }
is illegal if in one compilation unit, T is a typedef for int,
and in another, a typedef for double.
Note that in practice, certain violations are common, and will
work. For example:
inline void
f( int i )
{
assert( i < 20 ) ;
// ...
}
Practically speaking, there will not be many modules compiled
with NDEBUG defined, but if there are any, then this formally
has undefined behavior, but in practice, won't cause any
problems.
Additionally, when a member function is defined within a class
definition, it's implicitly "inline", so there the "inline"
keyword is superflous.
And that's it.
Except that once upon a time "inline" also worked as an
optimization hint.
The standard, including the latest draft, says that that's what
it should do.
However, modern compilers mostly just
ignore that,
Are you sure? A good compiler will not ignore it, unless the
optimizer really is capable of doing a better job. Some are,
but not that many.
and hinting is a very unreliable form of
communication anyway, prone to misunderstandings.
Like register before it, it really doesn't apply at the right
level. It's all or nothing for a given function (or variable),
where as what you generally want is to inline just certain call
sites (or the variable in just certain blocks of code). There
are ways around this, but they are wordy and awkward, and almost
never used.
The main difference between inline and register is that today,
almost every compiler can do a better job at allocating
registers than the programmer, using the keyword register,
precisely because it does so locally. Whereas for inline, this
is still not the usual case. It's an ugly hack (because who
wants code in the header), but at times, it's the only solution.
Using
"inline" that way is not recommended.
Use of inline in general is to be avoided in header files. It
increases coupling. Similarly, non-exported templates should be
avoided. In both cases, however, if you're stuck, and don't
have a better alternative... (If the profiler says you've got
to, you've got to.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34