templates and their compilation

P

pleexed

hello,
this is my first post in a newsgroup, i hope i do everything right :)

first of all, i am sure there have been a lot of "are templates slow?"
questions around, but i think what i would like to know is not that
general. furthermore, what i ask here may have hardly any impact on
the generated code size or performance; i am not trying to micro-
optimize anything, i am just curious how templates are compiled by
modern compilers of various vendors. i know that the compilers do not
behave the same, so whenever i speak of "compilers", i welcome any
information that is either special to one compiler or widely adopted
by most compilers.
by the way, i have done some searching prior to posting this, but
unfortunately i could not find satisfying answers. i would have done
some test myself if i knew assembler well enough to extract any
information out of the compiler generated code.

Q1)
i have heard that some compilers do not inline template functions or
classes, but i guess this information is quite outdated and modern
compilers inline them just as normal functions/classes, don't they?

Q2)
assume there is a template (member) function funct that has one (or
more) template arguments. funct does a lot of work, but the places it
actually makes any use of the template parameter are relatively rare.
so, all instatiations of funct have a lot of code in common, the
generic code is rather small. do compilers somehow "merge" that common
code so it is not duplicated everytime a new instantiation of funct
occurs?

Q3)
i am currently reading "Modern C++ Design" by Alexandrescu. There, he
demonstrates various techniques to evaluate expressions (might be the
wrong term in this case) at compile time. as an example, i wondered in
chapter 2.4 (here is the code in question: http://rafb.net/p/C9RwGV80.html
) how far compilers really optimizes this template.
if, for example, i instantiate NiftyContainer as follows:
NiftyContainer<int, false> x;
Here, the compiler could "redirect" every call to x.DoSomething(int*)
directly to x.DoSomething(int*, Int2Type<false>), without calling
x.DoSomething(int*) to avoid the calling overhead. do compilers do
that in practise or is that too complicated or even impossible for
more complex real-world code?

Q4)
as in the question above, Alexandrescu uses overloaded functions with
unused dummy arguments. if the compiler has access to the full source
code of the function, it may note that the argument really is unused
(and thus unnamed) and eliminate the overhead of passing the argument.
however, if the definition of the function is not accessible (for
example, it is "hidden" in a closed-source library), the compiler
cannot know whether the argument is used, so it has to pass it. how do
compilers behave in these situations?

Q5)
Alexandresu says that policy classes are either to be contained within
or inherited by the host classes, which makes sense. since only some
policies (and no traits, if i understood that correctly) have any
member data, the compiler could optimize the need to construct/
destruct the parent policy (in case of inheritance) or the member
instance (in case of containment) away. maybe, but i am not sure
whether this is possible for containment, it even could avoid
allocating the minimum size of one byte for the empty class; when used
with inheritance, this should be no problem, is it?

i hope i have stated my questions in an understandable way :)

thank you for possible answers in advance
 
G

Gianni Mariani

Q1)
i have heard that some compilers do not inline template functions or
classes, but i guess this information is quite outdated and modern
compilers inline them just as normal functions/classes, don't they?

You can easily test thus myth. Most compilers I have used recently do a
very good job of inlining template funcs when optimization is turned on.
Q2)
assume there is a template (member) function funct that has one (or
more) template arguments. funct does a lot of work, but the places it
actually makes any use of the template parameter are relatively rare.
so, all instatiations of funct have a lot of code in common, the
generic code is rather small. do compilers somehow "merge" that common
code so it is not duplicated everytime a new instantiation of funct
occurs?

I have yet to see a compiler merge generic code. However, the one time
(yes only once) where it made any sense for me to refactor the template
function, it was quite trivial to do this. In any case, code size, even
for multiple instantiations of "big" functions has never been a concern
for regular applications.
Q3)
i am currently reading "Modern C++ Design" by Alexandrescu. There, he
demonstrates various techniques to evaluate expressions (might be the
wrong term in this case) at compile time. as an example, i wondered in
chapter 2.4 (here is the code in question: http://rafb.net/p/C9RwGV80.html
) how far compilers really optimizes this template.
if, for example, i instantiate NiftyContainer as follows:
NiftyContainer<int, false> x;
Here, the compiler could "redirect" every call to x.DoSomething(int*)
directly to x.DoSomething(int*, Int2Type<false>), without calling
x.DoSomething(int*) to avoid the calling overhead. do compilers do
that in practise or is that too complicated or even impossible for
more complex real-world code?

I didn't look at the code, but it's quite possible that the compiler
will make the optimization if it makes sense.
Q4)
as in the question above, Alexandrescu uses overloaded functions with
unused dummy arguments. if the compiler has access to the full source
code of the function, it may note that the argument really is unused
(and thus unnamed) and eliminate the overhead of passing the argument.
however, if the definition of the function is not accessible (for
example, it is "hidden" in a closed-source library), the compiler
cannot know whether the argument is used, so it has to pass it. how do
compilers behave in these situations?

Nothing different here to regular functions.
Q5)
Alexandresu says that policy classes are either to be contained within
or inherited by the host classes, which makes sense. since only some
policies (and no traits, if i understood that correctly) have any
member data, the compiler could optimize the need to construct/
destruct the parent policy (in case of inheritance) or the member
instance (in case of containment) away. maybe, but i am not sure
whether this is possible for containment, it even could avoid
allocating the minimum size of one byte for the empty class; when used
with inheritance, this should be no problem, is it?

Most compilers now implement the empty base class optimization so there
is no inheritance overhead for empty classes.
 
P

pleexed

Q4)
Nothing different here to regular functions.
i may have expressed my question poorly; i did not intend to make this
question specific to template functions, i am curious to know how
compilers handle this in general.
Most compilers now implement the empty base class optimization so there
is no inheritance overhead for empty classes.
so, inheriting from policies instead of containing them as members
would save me a bit (actually, a byte) of memory and maybe some CPU
instructions? i kind of feel biased towards the containment approach
because i have a, perhaps irrational, "fear" of multiple inheritance,
which might be needed if i decide to inherit from one or more
policies, maybe in addition to an oridinary base class.

thank you for your reply
 
T

tony_in_da_uk

i may have expressed my question poorly; i did not intend to make this
question specific to template functions, i am curious to know how
compilers handle this in general.

Your original analysis was correct.
so, inheriting from policies instead of containing them as members
would save me a bit (actually, a byte) of memory and maybe some CPU
instructions? i kind of feel biased towards the containment approach
because i have a, perhaps irrational, "fear" of multiple inheritance,
which might be needed if i decide to inherit from one or more
policies, maybe in addition to an oridinary base class.

It's not good to second-guess the compiler optimisations, i.e. some
compilers might not waste space for empty contained objects (for which
the address isn't taken), and if they don't implement this
optimisation now they might do so in future. It has no practical
import, so you shouldn't let it dictate your coding. And how can we
respond to your irrational fears? If it was the '60s, maybe someone
would offer you a hug...? :) Don't let the Java/C# nonsense about
multiple inheritance pollute your thinking - more a case of making up
criticisms for whatever they left out.

Cheers,

Tony
 
J

joe

so, inheriting from policies instead of containing them as members
would save me a bit (actually, a byte) of memory and maybe some CPU
instructions? i kind of feel biased towards the containment approach
because i have a, perhaps irrational, "fear" of multiple inheritance,
which might be needed if i decide to inherit from one or more
policies, maybe in addition to an oridinary base class.

thank you for your reply

As was mentioned else where, don't be afraid of multiple inheritance.
However,
if your policy has no state, then you don't need to either inherit nor
to have a
member. All of your methods can be invoked as Policy::method() where
needed. After all,
if there is no state data, they might as well be static methods in the
policy.

joe
 
P

pleexed

if there is no state data, they might as well be static methods in the

simple as it is, i have not even thought about this possibility ;)

thank you joe and Tony for your posts

still, Q3 is not really answered now. the optimization seems possible
to me, but i am not sure whether compilers detect this opportunity or
if the standard even allows this.
hopefully someone who knows the definite answer for any compiler will
post :>
 
F

Frank Birbacher

Hi!

still, Q3 is not really answered now. the optimization seems possible
to me, but i am not sure whether compilers detect this opportunity or
if the standard even allows this.

The compiler will inline the first call. So, yes, this is optimized away
on most compiliers in release mode.

Frank
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top