user611105
user611105

Reputation:

C++ Boolean evaluation

So I'm curious as to why this happens.

int main()
{
   bool answer = true;
   while(answer)
   {
      cout << "\nInput?\n";
      cin >> answer;
   }
return 0;
}

Expected behavior: 0 - Exits program, 1 - Prompts again, Any non-zero integer other than 1 - Prompts again

Actual behavior: 0 - As expected, 1 - As expected, Any non-zero integer other than 1 - Infinite loop

From http://www.learncpp.com/cpp-tutorial/26-boolean-values/

One additional note: when converting integers to booleans, 
the integer zero resolves to boolean false, 
whereas non-zero integers all resolve to true.

Why does the program go into an infinite loop?

Upvotes: 23

Views: 4049

Answers (2)

James McNellis
James McNellis

Reputation: 355187

In effect, the operator>> overload used for reading a bool only allows a value of 0 or 1 as valid input. The operator overload defers to the num_get class template, which reads the next number from the input stream and then behaves as follows (C++11 §22.4.2.1/6):

  • If the value to be stored is 0 then false is stored.

  • If the value is 1 then true is stored.

  • Otherwise true is stored and ios_base::failbit is assigned to err.

(err here is the error state of the stream from which you are reading; cin in this case. Note that there is additional language specifying the behavior when the boolalpha manipulator is used, which allows booleans to be inserted and extracted using their names, true and false; I have omitted these other details for brevity.)

When you input a value other than zero or one, the fail state gets set on the stream, which causes further extractions to fail. answer is set to true and remains true forever, causing the infinite loop.

You must test the state of the stream after every extraction, to see whether the extraction succeeded and whether the stream is still in a good state. For example, you might rewrite your loop as:

bool answer = true;
while (std::cin && answer)
{
    std::cout << "\nInput?\n";
    std::cin >> answer;
}

Upvotes: 24

James Youngman
James Youngman

Reputation: 3733

Because operator>> fails if the input is not 0 or 1, and when it fails, it does not consume input. So the loop consists of reading the digit and then un-reading it, repeatedly.

Try changing the code like this to see it:

if (cin >> answer) {
  cout << answer << endl;
} else {
  cerr << "oops" << endl;
  break;
}

Upvotes: 15

Related Questions