On 31 March 2014 13:07, Yury Usishchev wrote: > Hello! > > I have a question about test case in pr60687: > > template <typename CALLER> > void exec1(CALLER & caller) { > struct Me : public CALLER { > public: > Me(CALLER & caller) : CALLER(caller) {}; > void exec() { > if(0) exec1(*this); > } > } me(caller); > return me.exec(); > } > > int main(int, char**) { > struct Me0 {} me; > exec1(me); > return 0; > } > > Currently gcc fails to compile it with 'template > instantiation depth exceeds maximum' error > > But actually exec1 is not recursive, so we dont need > to instantiate all these templates. > > So the question is: > Is this behavior valid? Or maybe according to C++11 > standard we should be able to compile and run such code. I'm pretty sure what G++ is doing is allowed by the standard. The code above is only non-recursive because of the if(0) condition, but the exec1(*this) call still has to be calid C++, and to compile that statement the compiler has to do overload resolution, which means instantiating the function template that would be called. The standard does not require compilers to do dead code elimination and remove the statement following the condition, that's an optimisation, not a requirement of the language. Even if it was required the eliminated call would still have to be valid C++ and so would require template instantiation, and that recursively instantiates the next function template and so on. Because the code above depends on a constant you could terminate the recursion quite easily by overloading the function and dispatching on the value of that constant: #include <type_traits> template <typename CALLER> void exec1(CALLER & caller, std::integral_constant<int, 0>) { } template <typename CALLER, int N = 1> void exec1(CALLER & caller, std::integral_constant<int, N> = {}) { struct Me : public CALLER { public: Me(CALLER & caller) : CALLER(caller) {}; void exec() { exec1(*this, std::integral_constant<int, 0>()); } } me(caller); return me.exec(); } int main(int, char**) { struct Me0 {} me; exec1(me); return 0; } For the original testcase in the bug report I don't think that's possible, because the condition is a run-time value not a constant. In that case it should be obvious that the compiler cannot easily prove the recursion terminates without performing some non-trivial optimisations, but those optimisations don't happen until after template instantiation has been completed.