On Thursday, 27 June 2013 at 03:47:39 UTC, Jonathan M Davis wrote:
That's _very_ dependent on what the function does. A prime
counter-example
would be overloaded operators like opBinary which uses their
string template
arguments in mixins within the function, thereby generating
completely
different functions. And I believe that that is by far the more
common use of
strings as template parameters.
This may be true. Any kind of optimization would probably have to
ignore most operator functions. Another heavy use of strings,
however, is string lambdas. Checking if two string lambdas are
the same is a simple string comparison, and then that template
can be compiled once and all copies can be ellided. Then it's
just a call to that template wherever it is used with that
particular lambda in the program. I think this could be done with
any template that accepts some kind of lambda function, but it
may be somewhat tricky currently to figure out if two non-string
lambda are equal, and I believe that DMD currently generates a
unique lambda wherever one is used.
Also, when using strings and integral values such as __FILE__
and __LINE__,
the functions _do_ have different code.
auto foo(string file = __FILE__, size_t line = __LINE__)(Bar b)
{
auto f = file;
auto l = line;
....
}
ends up generating different code depending on the values of
file or line. The
code is _not_ identical. The only way for the code not to vary
is for those
arguments to be runtime arguments. If they're compile-time
arguments, then by
definition, they affect the generated code if they're ever used.
I do know that the code generated is different. Turning
compile-time arguments into run-time arguments will,
unfortunately, completely defeat the point, as you know. It's a
tricky problem, because you can't just partially compile a
function and then change the compile-time arguments as you
encounter each new instantiation. If we could do that, we
wouldn't have this problem, and we would probably be using Common
Lisp.
Yes, it is theoretically possible for the compiler to use the
same template
definition under certain circumstances (especially if you're
dealing with
something like a templated struct that ultimately ends up with
exactly the
same layout across multiple instantiations), but the only way
that the
compiler could avoid duplicating the code with something like
__FILE__ and
__LINE__ being used as template arguments is to translate them
into function
arguments, because if the function has only one definition,
then it can't have
different values for the file or line number.
This is something that could be potentially solved on the binary
level, if you're sure that varying the value of a template
argument will not affect how it functions. I'm not an expert on
how DMD works, but could this possibly be done after the native
code is generated, but before optimizations are performed? Just
throwing out ideas.