I ran into a rather subtle bug when using std::minmax
with structured bindings. It appears that passed rvalues will not always be copied as one might expect. Originally I was using a T operator[]() const
on a custom container, but it seems to be the same with a literal integer.
#include <algorithm>
#include <cstdio>
#include <tuple>
int main()
{
auto [amin, amax] = std::minmax(3, 6);
printf("%d,%d\n", amin, amax); // undefined,undefined
int bmin, bmax;
std::tie(bmin, bmax) = std::minmax(3, 6);
printf("%d,%d\n", bmin, bmax); // 3,6
}
Using GCC 8.1.1 with -O1 -Wuninitialized
will result in 0,0
being printed as first line and:
warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]
Clang 6.0.1 at -O2
will also give a wrong first result with no warning.
At -O0
GCC gives a correct result and no warning. For clang the result appears to be correct at -O1
or -O0
.
Should not the first and second line be equivalent in the sense that the rvalue is still valid for being copied?
Also, why does this depend on the optimization level? Particularly I was surprised that GCC issues no warning.