繁体   English   中英

`if constexpr` vs`if`根据编译器优化和代码性能

[英]`if constexpr` vs `if` in light of compiler optimization and code performance

考虑一个非常重要的功能模板func 它可以用T=Type1或其他类型实例化。 部分功能逻辑依赖于T实例化。

一个可以显式使用if constexpr (代码B)或使用香草if代替(代码A),而编译器可能优化代码。

但是,我想知道,没有constexpr (代码A)的实现有何不同? 编译器是否能够在实例化时检测if (在代码A中)哪个分支在编译时使用? 它仍然(换码)生成代码效率不高?

代码A. 如果没有 if constexpr

template<class T>
void func(T argument)
{
    // some general type-independent logic
    if (std::is_same<Type1,T>::value)
    {
        // do something
    }
    else
    {
        // do something else
    }
    // some general type-independent logic
}

B.代码随着 if constexpr

template<class T>
void func(T argument)
{
    // some general type-independent logic
    if constexpr (std::is_same<Type1,T>::value)
    {
        // do something
    }
    else
    {
        // do something else
    }
    // some general type-independent logic
}

这两个代码A&B编译,如do somethingdo something else都能很好地形成任何T

有一些类似的问题:

如果代码B由于某种原因(当两个分支都是格式良好的时候)优于代码A时,上述问题不会回答。

我看到的唯一优势是明确告诉程序员这if是编译时; 但是,我会说条件表达式是不言自明的。

if constexpr不打算进行优化。 编译器非常擅长优化if (true)if (false)的分支(因为我们正在讨论常量表达式,这就是它归结为)。 这是OP中示例的一个Godbolt演示 - 你会注意到gcc和clang,即使在-O0 ,也不会为简单的if发出分支。

if constexpr是为了确保只实例化 if一个分支。 这对于编写模板非常重要和有价值 - 因为现在我们实际上可以在同一函数体内编写有条件的编译代码而不是编写多个人工函数来避免实例化。

也就是说,如果你的条件是一个已知的常量表达式 - 只要总是使用if constexpr ,无论你是否需要实例化的好处。 这样的决定没有任何缺点。 这使得读者更清楚这种情况确实是不变的(因为否则它甚至不会编译)。 这也将迫使表达的评价作为常数( 轻微变异导致的gcc发出分支在-O0 ,以为不-O1 ),它与即将加入is_constant_evaluated()有可能成为从长远来看更重要(甚至可能否定我的开头段落)。


我看到的唯一优势是明确告诉程序员这是否是编译时; 但是,我会说条件表达式是不言自明的。

为了具体解决这个问题,是的, std::is_same<X, Y>::value是“不言自明”的,它是一个常量表达式...因为我们碰巧熟悉std::is_same 但是foo<X>::value是一个常量表达式还是foo<X>() + bar<Y>()是一个常量表达式还是比这更复杂的任何东西都不太明显。

它看if constexpr使得它的编译时不言自明,而不是条件本身的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM