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.

Reply via email to