Home > Software engineering >  Is this gcc and clang optimizer bug with minmax and structured binding?
Is this gcc and clang optimizer bug with minmax and structured binding?

Time:03-06

This program, built with -std=c 20 flag:

#include <iostream>

using namespace std;

int main() {
  auto [n, m] = minmax(3, 4);
  cout << n << " " << m << endl;
}

produces expected result 3 4 when no optimization flags -Ox are used. With optimization flags it outputs 0 0. I tried it with multiple gcc versions with -O1, -O2 and -O3 flags.

Clang 13 works fine, but clang 10 and 11 outputs 0 4198864 with optimization level -O2 and higher. Icc works fine. What is happening here?

The code is here: https://godbolt.org/z/Wd4ex8bej

CodePudding user response:

The overload of std::minmax taking two arguments returns a pair of references to the arguments. The lifetime of the arguments however end at the end of the full expression since they are temporaries.

Therefore the output line is reading dangling references, causing your program to have undefined behavior.

Instead you can use std::tie to receive by-value:

#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;
}

Or you can use the std::initializer_list overload of std::minmax, which returns a pair of values:

#include <iostream>
#include <algorithm>

int main() {
  auto [n, m] = std::minmax({3, 4});
  std::cout << n << " " << m << std::endl;
}
  • Related