https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70470

            Bug ID: 70470
           Summary: std::min uninitialized value
           Product: gcc
           Version: 5.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: shaun.endres at numerica dot us
  Target Milestone: ---

Summary:

The following code incorrectly compute the value of x and will yield a warning
about an uninitialized variable:

const double &x = std::min(std::abs(1.0), 2.0);
if (x != 1) { std::cout << "Incorrect Result!" << std::endl; }

This will give a warning of:

warning: ‘<anonymous>’ is used uninitialized in this function [-Wuninitialized]

And will incorrectly compute the value of x to be zero, which will print
"Incorrect Result!" to the screen.

However, if you store the result in a double instead of a const double &, then
the result is computed correctly and no warning is given.  Additionally,
breaking up the std::min and std::abs into two statements will also make the
problem disappear.

***********

Details:

g++ --version => g++ (GCC) 5.3.0
uname -r => 2.6.32-573.12.1.el6.x86_64

Full Source:

#include <cmath>
#include <algorithm>
#include <iostream>

int main()
{
  double x = 1.0;
  double y = 2.0;

  double xx = std::abs(x);

  const double& z1 = std::min(xx, y);
  const double& z2 = std::min(std::abs(x), y);
  double z3 = std::min(xx, y);
  double z4 = std::min(std::abs(x), y);

  std::cout << "z1: " << z1 << std::endl;
  std::cout << "z2: " << z2 << std::endl;
  std::cout << "z3: " << z3 << std::endl;
  std::cout << "z4: " << z4 << std::endl;

  if ( z1 != 1 ) std::cerr << "Incorrect z1: " << z1 << " != 1" << std::endl;
  if ( z2 != 1 ) std::cerr << "Incorrect z2: " << z2 << " != 1" << std::endl;
  if ( z3 != 1 ) std::cerr << "Incorrect z3: " << z3 << " != 1" << std::endl;
  if ( z4 != 1 ) std::cerr << "Incorrect z4: " << z4 << " != 1" << std::endl;

  return 0;
}

Compiling:

g++ -o test_min -Wall -O2 test_min.cpp

Compilation Output:

test_min.cpp: In function ‘int main()’:
test_min.cpp:23:3: warning: ‘<anonymous>’ is used uninitialized in this
function [-Wuninitialized]
   if ( z2 != 1 ) std::cerr << "Incorrect z2: " << z2 << " != 1" << std::endl;
   ^

Execution Output:

z1: 1
z2: 0
z3: 1
z4: 1
Incorrect z2: 0 != 1

Notes:

I also tried this on gcc 4.4 and that did not seem to have the same issue.
If you remove the -O2 flag from the compilation command, then the issue goes
away.  (Adding -O1 and -O3 will also cause the issue.)

Reply via email to