I wonder whether for long loops we can take advantage of tail recursion for constexpr in C++11?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
By the rules in
[implimits], an implementation is permitted to put a recursion depth limit onconstexprcalculations. The two compilers which have completeconstexprimplementations (gcc and clang) both apply such a limit, using the default of 512 recursive calls as suggested by the standard. For both of these compilers, as well as any other implementation which follows the standard’s suggestion, a tail recursion optimization would be essentially undetectable (unless the compiler would otherwise crash before reaching its recursion limit).An implementation could instead choose to only count calls for which it could not apply a tail-recursion optimization in its recursion depth limit, or to not provide such a limit. However, such an implementation would probably be doing a disservice to its users, since it would be likely to either crash (due to a stack overflow) or fail to terminate on
constexprevaluations which recurse deeply or infinitely.With regard to what happens when the recursion depth limit is reached, Pubby’s example raises an interesting point.
[expr.const]p2specifies thatis not a constant expression. Therefore, if the recursion limit is reached in a context which requires a constant expression, the program is ill-formed. If a
constexprfunction is called in a context which does not require a constant expression, the implementation is not generally required to attempt to evaluate it at translation time, but if it chooses to, and the recursion limit is reached, it is required to instead perform the call at runtime. On a complete, compilable test program:GCC says:
and clang says:
If we modify the code so that the evaluation is not required to occur at translation time:
then both compilers accept it, and generate code which computes the result at runtime. When building with
-O0, this code fails due to stack overflow. When building with-O2, the compilers’ optimizers transform the code to use tail recursion and the code functions correctly (but note that this tail recursion is unrelated toconstexprevaluation).