在 clang 下,以下函数为尾递归函数生成目标代码:
template<typename T>
constexpr bool is_prime(T number, T limit, T counter)
{
return counter >= limit
? number % limit != 0
: number % counter
? is_prime(number, number / counter, counter + 2)
: false;
}
template<typename T>
constexpr bool is_prime(T n)
{
return n == 2 || n == 3 || n == 5
? true
: n <= 1 || n % 2 == 0
? false
: is_prime(n, n / 3, T{3});
}
但是改变一行(让布尔结果“非规范化”),它停止生成尾递归目标代码:
template<typename T>
constexpr bool is_prime(T number, T limit, T counter)
{
return counter >= limit
? number % limit // changed here
: number % counter
? is_prime(number, number / counter, counter + 2)
: false;
}
template<typename T>
constexpr bool is_prime(T n)
{
return n == 2 || n == 3 || n == 5
? true
: n <= 1 || n % 2 == 0
? false
: is_prime(n, n / 3, T{3});
}
是铿锵声未能正确优化它还是有合理的原因?
要强制运行时评估,x
是运行时积分素数≥ 13
(一次递归)或足够大的 constexpr 素数,由于递归深度大,会阻止编译时评估:
is_prime(x);