"constexpr if" vs "if" 与优化 - 为什么需要"constexpr"?

"constexpr if" vs "if" with optimizations - why is "constexpr" needed?

本文关键字:if constexpr 为什么 优化 vs      更新时间:2023-10-16

c 1z将根据条件将" constexpr"引入" constexpr" - 如果将一个分支之一根据条件删除。似乎很合理且有用。

但是,没有constexpr关键字不可能做到吗?我认为在编译期间,编译器应该知道在编译时间是否已知。如果是,即使是最基本的优化级别也应删除不必要的分支。

例如(请参阅Godbolt:https://godbolt.org/g/ipy5y5):

int test() {
    const bool condition = true;
    if (condition) {
      return 0;
    } else {
      // optimized out even without "constexpr if"
      return 1;
    }
}

Godbolt Explorer表明,即使使用-O0的GCC -4.4.7也没有编译"返回1",因此它实现了Constexpr的承诺。显然,当条件是constexpr函数的结果时,这种旧的编译器将无法做到这一点,但事实仍然是:现代编译器知道条件是否是constexpr,并且不需要我明确地告诉它。

所以问题是:

为什么在" constexpr"中需要" constexpr"?

这很容易通过示例解释。考虑

struct Cat { void meow() { } };
struct Dog { void bark() { } };

template <typename T>
void pet(T x)
{
    if(std::is_same<T, Cat>{}){ x.meow(); }
    else if(std::is_same<T, Dog>{}){ x.bark(); }
}

调用

pet(Cat{});
pet(Dog{});

将触发汇编错误 wandbox示例,因为if语句的两个分支都必须很好地形成。

prog.cc:10:40: error: no member named 'bark' in 'Cat'
    else if(std::is_same<T, Dog>{}){ x.bark(); }
                                     ~ ^
prog.cc:15:5: note: in instantiation of function template specialization 'pet<Cat>' requested here
    pet(Cat{});
    ^
prog.cc:9:35: error: no member named 'meow' in 'Dog'
    if(std::is_same<T, Cat>{}){ x.meow(); }
                                ~ ^
prog.cc:16:5: note: in instantiation of function template specialization 'pet<Dog>' requested here
    pet(Dog{});
    ^

更改pet使用if constexpr

template <typename T>
void pet(T x)
{
    if constexpr(std::is_same<T, Cat>{}){ x.meow(); }
    else if constexpr(std::is_same<T, Dog>{}){ x.bark(); }
}

仅要求分支可解析 - 只有与条件匹配的分支需要良好形成 Wandbox示例。。

摘要

pet(Cat{});
pet(Dog{});

将根据预期进行编译和工作。