编译器是否可以在 constexpr 函数中省略"not-taken"分支的计算?

May a compiler elide the evaluation of the "not-taken" branch in a constexpr function?

本文关键字:not-taken 分支 计算 中省 是否 函数 constexpr 编译器      更新时间:2023-10-16

在试图回答Mehrdad的问题时,我编写了下面的小函数(在liveworkspace中运行):

template <typename T, unsigned low, unsigned high>
static constexpr auto highest_index_in() ->
   typename std::enable_if<high >= low, unsigned>::type
{
   return low == high                 ? low :
          high == low + 1             ? (exists<T, high>() ? high : low) :
          exists<T, (high + low)/2>() ? highest_index_in<T, (high+low)/2, high>() :
                                        highest_index_in<T, low, (high+low)/2>();
} // highest_index_in

(其中exists = 0 (1))

编译非常慢(在liveworkspace上),并且试图使用宽范围完全失败,编译器崩溃([0, ~0u]不工作…)。

我相信我正确地实现了递归(我很高兴有人反驳),但是…

因此问题来了:在计算这里的各种三元操作符调用时,编译器是否可以忽略未取分支的计算?

不,编译器不能跳过三元操作符的未取分支的求值,因为这样做意味着编译器首先必须确定在任何可能导致程序格式错误的分支中没有冲突的重载和/或模板特化。为了进行这种判断,编译器必须有效地实例化分支上使用的模板,并对函数执行重载解析。