<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jul 16, 2018, at 5:08 AM, degski via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On 16 July 2018 at 11:06, Csaba Raduly <span dir="ltr" class=""><<a href="mailto:rcsaba@gmail.com" target="_blank" class="">rcsaba@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
You seem to be confusing run-time with compile-time. These errors are<br class="">
issued by the compiler while analyzing the source.</blockquote><div class=""><br class=""></div><div class=""> I understand, that it is at compile-time (otherwise it wouldn't be a problem). My point is, why is there in the 
case of recursive templates (as like in the example) a depth-limit at all. I 
mean at each recursive instantiation, there should be no need to 
increase the depth on each instantiation, as one can "forget" about 
the ones already instantiated, "they did not match".</div><div class=""><br class="">

</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There is no call stack yet.<br class=""></blockquote><div class=""><br class=""></div><div class=""> Well, obviously I know nothing about how it works under the hood (and the issue is not particular to clang, this is how all c++compilers work), but I interpreted the fact that there is a depth at all, that there must be some kind of stack-like mechanism.<br class=""></div></div><div class="gmail_quote"><br class=""></div><div class="gmail_quote">Referring to prolog, the compiler/interpreter would translate such a <b class="">tail-recursive call</b> (which would fill the prolog-call-stack, if taken at face-value) into iteration (by re-using the same stack-frame), which allows the "depth" to be arbitrarily deep (as there is non).</div></div></div></div></blockquote><div><br class=""></div>We all know what tail-recursion is.  Template instantiation is not naturally tail-recursive from the perspective of the compiler implementation because, while you might think of your template as a function which computes the constant initializer of the `value` member, class template instantiation is in fact a complex process which produces (and memoizes) an entire instantiated class, and (w.r.t your example) the recursive instantiation of the base clause is merely one step in that process.  In other words, the product of instantiation is a class, not a value, and the production of the value is not in tail position in the instantiation function.</div><div><br class=""></div><div>The compiler must provide a template-instantiation engine which produces actual classes in order to satisfy the main purpose of class template instantiation, which is to produce types that are normally usable in the language.  To naturally tail-recurse as you would like would require the compiler to include a recognizer of such templates and their uses which instead triggers a second, separate instantiation engine for the sole purpose of evaluating constant initializers in metaprograms; this would be a source of great redundancy, complexity, and bugs, and I suspect it would provide marginal value to most C++ compilations, even metaprogramming-heavy ones.</div><div><br class=""></div><div>Alternatively, within the compiler implementation we avoid using direct recursion when recursively instantiating class templates and instead apply generic recursion-to-iteration techniques, such as iterating on a worklist and resuming previous instantiations from a stored continuation point when they become unblocked.  However, that would require an extremely invasive restructuring of the compiler implementation, because it turns out that a rather shockingly long list of things in C++ can trigger class template instantiation, from name lookup to essentially every aspect of type-checking, and they would all need to be restructured to be paused and resumed.  So instead we use direct recursion like pretty much every other C++ implementation, meaning we cannot recursively instantiate templates to an infinite depth without blowing out the stack.</div><div><br class=""></div><div>John.</div></body></html>