代码之家  ›  专栏  ›  技术社区  ›  Paul Jurczak

这是最小最大值和结构化绑定的gcc和叮当优化程序错误吗?

  •  2
  • Paul Jurczak  · 技术社区  · 4 年前

    这个程序是用 -std=c++20 旗帜:

    #include <iostream>
    
    using namespace std;
    
    int main() {
      auto [n, m] = minmax(3, 4);
      cout << n << " " << m << endl;
    }
    

    产生预期的结果 3 4 当没有优化标志时 -Ox 都用过了。通过优化标记,它可以输出 0 0 .我用多个gcc版本和 -O1 , -O2 -O3 旗帜。

    Clang13工作正常,但是Clang10和11输出 0 4198864 具有优化级别 -氧气 更高。Icc工作正常。这里发生了什么?

    代码如下: https://godbolt.org/z/Wd4ex8bej

    1 回复  |  直到 4 年前
        1
  •  4
  •   user17732522    4 年前

    超负荷的 std::minmax 获取两个参数将返回对参数的一对引用。然而,由于这些论点是临时性的,它们的生命周期在完整表达的末尾结束。

    因此,输出行正在读取悬空引用,导致程序具有未定义的行为。

    相反,你可以使用 std::tie 按价值收取:

    #include <iostream>
    #include <tuple>
    #include <algorithm>
    
    int main() {
      int n, m;
      std::tie(n,m) = std::minmax(3, 4);
      std::cout << n << " " << m << std::endl;
    }
    

    或者你可以使用 std::initializer_list 超载 最小值 ,返回一对值:

    #include <iostream>
    #include <algorithm>
    
    int main() {
      auto [n, m] = std::minmax({3, 4});
      std::cout << n << " " << m << std::endl;
    }