Clang 对递归 constexpr 函数的好奇错过了优化

Ika*_*ros 5 c++ clang compiler-optimization constexpr clang++

今天我想测试一下,Clang 如何转换两个函数的递归幂,并注意到即使使用已知指数,即使使用 constexpr 也不会优化递归。

#include <array>
constexpr unsigned int pow2_recursive(unsigned int exp) {
    if(exp == 0) return 1;
    return 2 * pow2_recursive(exp-1);
}

unsigned int pow2_5() {
    return pow2_recursive(5);
}
Run Code Online (Sandbox Code Playgroud)

pow2_5 被编译为对 pow2_recursive 的调用。

pow2_5():                             # @pow2_5()
        mov     edi, 5
        jmp     pow2_recursive(unsigned int)     # TAILCALL
Run Code Online (Sandbox Code Playgroud)

但是,当我在需要在编译时知道结果的上下文中使用结果时,它将在编译时正确计算结果。

unsigned int pow2_5_arr() {
    std::array<int, pow2_recursive(5)> a;
    return a.size();
}
Run Code Online (Sandbox Code Playgroud)

被编译为

pow2_5_arr():                        # @pow2_5_arr()
        mov     eax, 32
        ret
Run Code Online (Sandbox Code Playgroud)

以下是 Godbolt 中完整示例的链接:https ://godbolt.org/z/fcKef1

那么,我在这里错过了什么吗?有什么可以在运行时改变结果的原因吗,pow2_5 不能像 pow2_5_arr 一样优化?