7
#include <ios>
#include <iostream>
#include <map>

using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  map<int, int> v;
  int i;
  int t;
  while (cin >> i) {
    v[i] = t++;
  }
  auto mi = i;
  auto mt = t;
  for (const auto p : v) {
    if (p.second < mt) {
      mi = p.first;
      mt = p.second;
    }
  }
  cout << mi << '\n';
  return 0;
}

The abovementioned program makes heavy use of an uninitialized variable t, but GCC does not report it with -Wall or -Wuninitialized. Why is it so?

It is worth noting that Clang catches it:

main.cpp:13:12: warning: variable 't' is uninitialized when used here [-Wuninitialized]
    v[i] = t++;
           ^

Used g++ (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2).

Used clang version 4.0.1 (tags/RELEASE_401/final).


As you can see in https://godbolt.org/g/kmYMC1 GCC 7.2 does not report it even when it should. I will create a ticket in GCC's issue tracker.

Bernardo Sulzbach
  • 1,293
  • 10
  • 26

2 Answers2

8

g++'s warning flag is not called -Wuninitialized: it is called -Wmaybe-uninitialized.

Also, as Jonathan Wakely noted in his answer, g++ is able to detect usage of uninitialized variables only when optimizations are enabled.

Enabling both -Wmaybe-initalized and optimizations produces the expected warning: https://godbolt.org/g/3CZ6kT

Note that -Wmaybe-initalized is enabled by default with both -Wall and -Wextra.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • I see. But the man page for it says "Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a "setjmp" call.", which seems to be the cause when an auto is initialized using it, right? – Bernardo Sulzbach Nov 15 '17 at 12:36
  • Relevant Compiler Explorer (with GCC 7.2): https://godbolt.org/g/dQAAqQ – Bernardo Sulzbach Nov 15 '17 at 12:42
  • 1
    @BernardoSulzbach: yes, that should probably fire a warning. I suggest minimizing the example and creating a bug report on the gcc bug tracker. – Vittorio Romeo Nov 15 '17 at 12:56
  • "when an auto is initialized using it" doesn't mean anything. There's no such thing as "an auto". Anyway, the warning should be given when incrementing the uninitialized variable, `t++`, not when copying it into `mt`, and if you enable optimization then GCC does warn. – Jonathan Wakely Nov 15 '17 at 13:30
  • 2
    @VittorioRomeo as the manual says, `-Wmaybe-uninitialized` is enabled by both `-Wall` and `-Wextra` – Jonathan Wakely Nov 15 '17 at 13:33
6

GCC can only detect uninitialized variables when optimization is enabled, because the logic for tracking the values of variables is part of the optimization machinery.

If you compile with -O -Wall you get a warning:

<source>: In function 'int main()':
12 : <source>:12:13: warning: 't' may be used uninitialized in this function [-Wmaybe-uninitialized]
     v[i] = t++;
            ~^~
Compiler exited with result code 0

https://godbolt.org/g/327bsi

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521