Apache C++ Standard Library User's Guide

## 29.1 About Flags

It probably comes as no surprise that streams have an error state. When an error occurs, flags are set in the state according to the general category of the error. Flags and their error categories are summarized in Table 30:

#### Table 30: Flags and corresponding error categories

iostate flag | Error category
`ios_base::goodbit` | Everything's fine
`ios_base::eofbit` | An input operation reached the end of an input sequence
`ios_base::failbit` | An input operation failed to read the expected character, or an output operation failed to generate the desired characters
`ios_base::badbit` | Indicates the loss of integrity of the underlying input or output sequence or some other serious error

Note that the flag `std::ios_base::goodbit` is not represented by any one bit; its value, `0`, indicates the absence of any error flag. This means the stream is OK. By convention, all input and output operations have no effect once the stream state is different than 0.

There are several situations when both `eofbit` and `failbit` are set; however, the two have different meanings and do not always occur in conjunction. The flag `eofbit` is set when there is an attempt to read past the end of an input sequence. This occurs in the following two typical examples:

1. Assume the extraction happens character-wise. Once the last character is read, the stream is still in good state; `eofbit` is not yet set. Any subsequent extraction, however, is considered an attempt to read past the end of the input sequence. Thus, `eofbit` is set. (Later, we'll see that `failbit` is set as well.)

2. If you do not read character-wise, but extract an integer or a string, for example, you always read past the end of the input sequence. This is because the input operators read characters until they find a separator, or hit the end of the input sequence. Consequently, if the input contains the sequence `... 912749<eof>` and an integer is extracted, the `eofbit` flag (but not `failbit`) is set.

The flag `std::ios_base::failbit` is set as the result of a read or write operation that fails. For example, if you try to extract an integer from an input sequence containing only white spaces, the extraction of an integer fails, and the `failbit` is set. Let's see whether `failbit` would be set in the previous examples:

1. After reading the last available character, the extraction not only reads past the end of the input sequence; it also fails to extract the requested character. Hence, `failbit` is set in addition to `eofbit`.

2. In this case, the result is different. Although the end of the input sequence is reached by extracting the integer, the input operation does not fail and the desired integer is indeed read. In this situation only the `eofbit` is set.

In addition to these input and output operations, there are other situations that can trigger failure. For example, file streams set `failbit` if the associated file cannot be opened (see Section 30.2.2).

The flag `std::ios_base::badbit` indicates problems with the underlying stream buffer. These problems could be:

- Memory shortage. There is no memory available to create the buffer, or the buffer has size `0` for other reasons (such as being provided from outside the stream), or the stream cannot allocate memory for its own internal data, as with `std::ios_base::iword()` and `std::ios_base::pword()`.

- The underlying stream buffer throws an exception. The stream buffer might lose its integrity, as in memory shortage, or code conversion failure, or an unrecoverable read error from the external device. The stream buffer can indicate this loss of integrity by throwing an exception, which is caught by the stream and results in setting the `badbit` in the stream's state.

Generally, you should keep in mind that `badbit` indicates an error situation that is likely to be unrecoverable, whereas `failbit` indicates a situation that might allow you to retry the failed operation. The flag `eofbit` simply indicates the end of the input sequence.

What can you do to check for such errors? You have two possibilities for detecting stream errors:

- You can declare that you want to have an exception raised once an error occurs in any input or output operation.

- You can actively check the stream state after each input or output operation.

We explore these possibilities in the next two sections.