【问题标题】:C++ constexpr realization differencies [duplicate]C ++ constexpr实现差异[重复]
【发布时间】:2018-10-28 22:44:12
【问题描述】:

刚刚了解了 constexpr 函数并前往 godbolt 了解编译器如何优化代码并发现编译器的行为完全不同。

有如下代码:

constexpr int square(int num) {
    return num * num;
}

int main() {
    int a = square(2);
}

g++icc 编译器计算函数结果并将其分配给一个变量(如我所料),但 msvcclang 调用函数。

要使用优化,我们应该做额外的步骤:

constexpr int square(int num) {
    return num * num;
}

int main() {
    constexpr int c = square(2);
    int a = c;
}

这种行为有什么合理的解释吗?

godbolt 示例链接:https://godbolt.org/z/ez7luu

【问题讨论】:

    标签: c++ g++ c++14 constexpr clang++


    【解决方案1】:

    所有编译器都是正确的。

    constexpr 函数是可以根据情况在编译时或运行时计算的函数。

    假装不存在as-if rule,我们可以说当constexpr 函数的结果到达要求知道编译时间的某个地方时,编译器必须计算编译时间.

    例如,数组的大小

    int  a[square(10)];
    

    或模板参数

    std::array<int, square(10)>  a;
    

    constexpr 变量

    constexpr int  a { square(10) };
    

    在某些情况下,函数必须在运行时计算,例如在接收运行时已知输入值时;举例

    int a;
    
    std::cin >> a;
    
    int b { square(a) }; 
    

    否则编译器可以选择计算值是编译时还是运行时。

    在您的第一个版本中

    int a = square(2);
    

    我们在compiler-can-choose区域,因为2是已知的compile-time,所以编译器可以选择compile-time计算,但是要求的值不是constexpr变量,所以a编译时值不是必需的。

    您会看到两个编译器在计算编译时间,另外两个在计算运行时间。通常,这种行为很大程度上取决于优化级别。事实上,所有编译器都会为您的示例中的编译标志生成不同的输出after adding -O2

    在你的第二个版本中

     constexpr int c = square(2);
    

    square() 值是为 constexpr 变量请求的,因此所有编译器必须计算 square(2) 编译时间(他们可以这样做,因为 2 是一个已知值编译时)。

    【讨论】:

      猜你喜欢
      • 2014-04-18
      • 2020-04-18
      • 2013-05-23
      • 2013-02-01
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多