0

This looks like a g++ bug (possibly sanitizer related) to me but was I wondering if anyone with clang (given the gcc sanitizer is from clang afaik), or a different g++ version, will have different results?

This is a simple program which reads in 3 values from stdin from the user, attempts to parse them, and prints them (I also show the status of cin's flags in case anyone wants them)

#include <iostream>
using namespace std;
int main ()
{
        bool c1, c2, c3;
        cin >> c1 >> c2 >> c3;
        cout << boolalpha << "Good: " << cin.good();
        cout << " Bad: " << cin.bad();
        cout << " Fail: " << cin.fail();
        cout << " EOF: " << cin.eof();
        cout << endl;
        cout << c1 << ", " << c2 << ", " << c3 << ", " << endl;
        return 0;
}

Here's what my shell shows when compiled without sanitizers and run with user-provided values of "true false 1":

0:48:03: 0 aho@ubuntu ~/dev/cpp$ g++  -Wall  cpp1.cc -o a.out -g3  && ./a.out
true false 1
Good: false Bad: false Fail: true EOF: false
false, false, false, 

I find it a bit surprising that it didn't print "true, true, true" (I thought only '0' would be parsed to false, and anything else true), but that's besides the point. Here's the juicy bit: adding sanitizer flags but providing the same inputs shows different results:

0:48:21: 0 aho@ubuntu ~/dev/cpp$ g++  -Wall  cpp1.cc -o a.out -g3  -fsanitize=address -fsanitize=leak -fsanitize=undefined && ./a.out
true false 1
Good: false Bad: false Fail: true EOF: false
cpp1.cc:12:45: runtime error: load of value 23, which is not a valid value for type 'bool'
false, false, true, 

Final details (lmk if you want more)

gcc version 4.9.2 (Ubuntu 4.9.2-0ubuntu1~12.04)
Linux ubuntu 3.8.0-44-generic #66~precise1-Ubuntu SMP Tue Jul 15 04:01:04 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
aho
  • 304
  • 2
  • 11
  • 1
    In C++11, `cin >> c1` is required to set `c1` to `false` (since your input was not an integer); but prior to C++11 it was specified to leave `c1` unchanged. `c2` and `c3` remain indeterminate in both cases since the stream is already in a fail state as of failing to read `c1` (see [this thread](http://stackoverflow.com/questions/19522504/istream-behavior-change-in-c-upon-failure)). Your output is consistent with c3 being indeterminate. – M.M Nov 11 '15 at 01:57
  • ah, nice find! +1 from me thanks @M.M – aho Nov 11 '15 at 02:01

1 Answers1

3

boolalpha is off by default for cin. As written, your program expects numerical flags, i.e. 1 0 1. To support input like true false true you need to enable boolalpha:

    bool c1, c2, c3;
    cin >> std::boolalpha; // add this line
    cin >> c1 >> c2 >> c3;
Adam
  • 16,808
  • 7
  • 52
  • 98
  • Interesting, I thought I'd tried that without observing any differences, but now I can't reproduce the effect I was seeing; must've been on crack. Thanks, this works now so I'll close this. – aho Nov 11 '15 at 01:53