c++ - 带有模板 bool 参数的函数 : guaranteed to be optimized?

标签 c++ templates

在下面的模板化函数示例中,for 循环内的中心 if 是否保证被优化掉,只留下使用的指令?

如果不能保证优化(在 GCC 4、MSVC 2013 和 llvm 8.0 中),有哪些替代方案(最多使用 C++11)?

注意,这个函数没有做任何有用的事情,而且我知道这个特定的函数可以通过多种方式进行优化等等。但我想关注的是 bool 模板参数在生成代码时如何工作。

template <bool IsMin>
float IterateOverArray(float* vals, int arraySize) {

    float ret = (IsMin ? std::numeric_limits<float>::max() : -std::numeric_limits<float>::max());

    for (int x = 0; x < arraySize; x++) {
        // Is this code optimized by the compiler to skip the unnecessary if?
        if (isMin) {
            if (ret > vals[x]) ret = vals[x];
        } else {
            if (ret < vals[x]) ret = vals[x];
        }
    }

    return val;

}

最佳答案

理论上没有。 C++ 标准不仅允许编译器愚蠢,而且还允许编译器完全敌对。只要抽象机器行为保持不变,它就可以无缘无故地注入(inject)代码做无用的事情。1

实际上,是的。死代码消除和常量分支检测很容易,我检查过的每个编译器都消除了 if 分支。

请注意,两个分支都是在删除一个分支之前编译的,因此它们都必须是完全有效的代码。输出程序集的行为“好像”两个分支都存在,但分支指令(和无法访问的代码)不是抽象机器行为的可观察特征。

当然,如果您不进行优化,分支和死代码可能会保留下来,因此您可以使用调试器将指令指针移动到“死代码”中。

<小时/>

1 例如,没有什么可以阻止编译器将 a+b 实现为在汇编中调用 inc 的循环,或 a*b作为循环重复添加a。这是编译器在几乎所有平台上的敌对行为,但并未被标准禁止。

关于c++ - 带有模板 bool 参数的函数 : guaranteed to be optimized?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42228600/

相关文章:

c++ - Qt在特定代码后没有继续运行指令

c++ - 从 RGB 值构建像素

c++ - 如何在不关闭服务器套接字的情况下在 C++ 客户端的主循环中接收数据?

c++ - C++ 模板中的模板参数

c++ - undefined reference ,为什么

c++ - 为什么编译器会忽略模板类中的结构元素?

c++ - 在 Linux 上运行的开源软调制解调器?

c++ - Oculus Rift DK2 上的简单视频流

c++ - 模板c++的模板

c++ - A类的定义需要B类的定义,如何在不暴露B定义的情况下暴露A的公共(public)函数?