1

I am reading a book and it says:

To turn off a single condition, we use the rdstate member and the bitwise operators to produce the desired new state.
For example, the following turns off failbit and badbit but leaves eofbit untouched:
//turns off failbit and badbit but all other bits unchanged.
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);

I felt totally confused about what the code does.

Here's how I try to figure out:

  1. Find out what rdstate() returns.
    http://en.cppreference.com/w/cpp/io/basic_ios/rdstate.
    It returns a iostate object.

  2. Find out what iostate object is.
    http://en.cppreference.com/w/cpp/io/ios_base/iostate.
    It's a Bitmask Type and also I saw it's "/implementation defined/".

  3. Find out what Bitmask Type is and how iostate implements in my compiler.
    http://en.cppreference.com/w/cpp/concept/BitmaskType.
    typedef int iostate, visual c++.
    No helpful information. And I got stuck here.

So I still don't have a clue about what rdstate() returned value looks like and how that line of code work.

How does cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit); work?

Btw, how should I explore something new (in C++), any advice? I mean, I've checked the documentation and I found that's not very helpful. (e.g. Python and JavaScript docs are much easier to read and understand)

Rick
  • 7,007
  • 2
  • 49
  • 79

1 Answers1

3

How does cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit); work?

A stream has a certain state, well, it can have multiple states at once, as they aren't all orthogonal (e.g. it can be EOF and bad at the same time). Instead of defining N different state variables, one just takes a single one and reserves certain bits of that variable for the different, orthogonal states. Thus, if you want to check for a certain state, you have to either check for the certain bits (which bit has what meaning is implementation-defined and not very useful to know) or you use the provided functions like good(), eof() and alike. A table summarizing their behavior can be found e.g. here.

rdstate() returns exactly the complete state variable. So what this line of code means is: "Set the stream's state to the current one, but remove any failbit and any badbit. This is what is happening to a binary digit in a number if you AND it with the complement of the bit you want to remove, i.e. if you want to remove the first bit of 1101, you take the complement of 1000, which is 0111, and thus 1101 & 0111 == 0101. Similarly, if you want to set a certain bit inside the variable, you use the bitwise OR, e.g. 0101 | 1000 == 1101. For a useful answer exploring more on the bitwise operations, check out e.g. this one.

Btw, how should I explore something new (in C++), any advice? I mean, I've checked the documentation and I found that's not very helpful. (e.g. Python and JavaScript docs are much easier to read and understand)

The C++ docs most likely go into details of explaining the general notion of bitmasks, as this is a rather old, but common approach in C. Nowadays, it should be rather considered a relic in C++ as it is too confusing for beginners, but it still prevails due to backwards-compatibility.

Jodocus
  • 7,493
  • 1
  • 29
  • 45
  • May I ask the difference between `setstate` function and `clear`? They seems do the same thing. – Rick Jun 11 '18 at 10:23
  • 1
    @Rick You may ask. According to the [reference](http://en.cppreference.com/w/cpp/io/basic_ios/setstate), "Sets the stream error flags state in addition to currently set flags. Essentially calls `clear(rdstate() | state)`. May throw an exception." – Jodocus Jun 11 '18 at 10:35
  • Yes, I see that. But what's the logic doing this **or** operation? `rdstate() | state` – Rick Jun 11 '18 at 10:36
  • Ok I see. It's **adding extra state**, while `clear` is overriding the whole thing. – Rick Jun 11 '18 at 10:41