* James Kanze, on 06.07.2010 11:55:
* James Kanze, on 05.07.2010 19:14:
[...]
Consider how a compiler would have to treat it in order to
inline everything that's technically 'inline', which for Boost
is most everything.
I was under the impression that the parts of Boost which are
header only were header only because they were templates, not
because they were inline.
Nobody's said that those parts (most of Boost) are header-only
because they're inline.
They're inline because they're header-only.
Except that the parts I looked at aren't inline, even when
they're header only.
On the contrary of your impression, the Boost parts that
require separate compilation are in general only those where
there are system dependencies.
What are the system dependencies in boost::format, or
boost::regex?
Starting at "A", the non-template "Any" class is wholly inline.
Maybe the author thought it needed the performance boost? (I
don't know. But most of the functions look pretty trivial, so
the author might have assumed that inline would provide
a significant performance boost.)
But you're right that most of the Boost stuff is templated.
The point is that most places where there is a dependency on
non-templated stuff, that stuff is defined 'inline' (using
that keyword or by defining member functions directly in
a class definition or by pseudo-templating and typedef, which
results in the same) in order to support the header-only
design goal.
I don't know. I've not looked at enough to say "most". Most of
my uses of Boost have been the templated stuff like bind, where
of course, inlining would be used because you want the actual
functions to disappear in the generated code (since they are
used for compiler internal logic, and not to do anything).
E.g. the two I use regularly, g++ and msvc.
G++ doesn't. On the other hand, g++ inlines any function whose
definition is visible, so it doesn't make much difference.
I'm not using this stuff, so I don't go around remembering the
details. I just know about it in general. So I had to look it
up for you, which took some time; it'd be better if you looked
up such things yourself, I think, and if you were then unable
to find anything, reporting that and /then/ asking.
// g++
inline void foo (const char) __attribute__((always_inline));
This causes g++ to attempt to inline the function for non-optimized build.
// g++
inline void foo (const char) __attribute__((gnu_inline));
This purportedly prevents g++ from emitting a linkable
definition, i.e. always inline.
Both of which are more than just a hint (especially the second).
// g++
inline void foo (const char) __attribute__((noinline));
This prevents the function from being machine-code-level inlined.
G++ offers other options than just straight "inline". But
they're only needed in special cases---normally, for
optimization, you specify inline. In the case of g++, it works
more or less as expected.
And there are some macros to support this stuff, plus some
more general compiler options, including some PC-specific
options.
// msvc
class X
{
__declspec(noinline) int mbrfunc()
{
return 0;
} // will not inline
};
// msvc
class X
{
__forceinline int mbrfunc()
{
return 0;
} // will always inline
};
I wrote the last example off the cuff, not copied from docs;
check it if you're really interested in this stuff and not
just asking questions willy-nilly.
Again, both your examples do more than just "inline". I think
that "inline" in MSVC works pretty much as the committee
intended as well: you aren't guaranteed that the function will
be inlined, but if the compiler can reasonably do so, it will.
Since that POV doesn't square with reality there is presumably
some assumption that doesn't hold, yes?
The compilers I've familiar with (MSVC, g++ and Sun CC) do take
"inline" to be a serious hint, and respect it. Which
corresponds to the committee's expressed intention: "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."
Uhm, except for the difference there is no difference...
Anyway, thanks!, I didn't know about that. I thought all the
difference was in the context, how the language is used in
modern programming (and hence what compilers do).
Compilers do what they've always done with regards to inline.
(Well, actually, the respect it a lot more than they used to.
Some of the earlier compilers wouldn't inline a function which
contained a loop.) Nothing has changed with respect to inline
since the original version of the standard has been adopted.
(And it is still banned by most coding guidelines, except in
exceptional cases.)
[snip]
It's spanned a fairly large number of application domains.
Yeah, but I think those application domains must have been
similar in some fundamental way. E.g. you're the only person
I know who uses the Boehm garbage collector regularly. Which
I believe influences the design of things.
Actually, I know people who use the Boehm collector more than
I do. A lot of my work involves contexts where I can't use it,
for various reasons.
The only real common characteristic of my work has been that
most of the projects involved a fairly large number of people.
So code had to be written in ways that made it easier to
understand and maintain. Which leads to avoiding inline as much
as possible (and avoiding templates in a lot of cases, as well,
since they suffer from the same problem).