问题
This is an example extracted from section 10.3.3 Input of User-defined Types from the book "The C++ Programming Language" second edition, by B. Stroustrup. The code is old but still compiles with minor changes. Example:
#include <istream> #include <complex> using namespace std; istream& operator>>(istream& s, complex<double>& a) { // input formats for a complex; "f" indicates a float: // // f // (f) // (f, f) double re = 0, im = 0; char c = 0; s >> c; if( c == '(' ) { s >> re >> c; if( c == ',' ) s >> im >> c; if( c != ')' ) s.clear(ios::badbit); // set state } else { s.putback(c); s >> re; } if( s ) a = complex<double>(re, im); return s; }
Despite the scarcity of error-handling code, this will actually handle most kinds of errors. The local variable
c
is initilized to avoid having its value accidentally'('
after a failed operation. The final check of the stream state ensures that the value of the argumenta
is changed if everything went well.
I failed to understand the phrase emphasized above.
回答1:
If s >> c
fails then c
is not written to.
If c
was uninitialized , it remains uninitialized at the point of the test if( c == '(' )
. Reading an uninitialized char
causes undefined behaviour.
The author is talking about a possible way that this undefined behaviour might manifest itself.
The suggested fix of char c = 0;
relies on the fact thats.putback(c);
does nothing if s
is not good()
. This is OK, although IMHO it would be clearer to write:
char c;
s >> c;
if ( !s )
return s;
Then anybody reading the code can immediately see that it behaves properly in case of error; instead of having to thread their way through the flow of the function and check that no other operations will do anything unexpected.
回答2:
Consider what happens if we didn't initialize c
:
char c;
s >> c;
if (c == '(') { ... }
We are not checking to see if >>
succeeded or failed. So if c == '('
, it could be for one of two reasons:
- The
>>
succeeded and we retrieved the character'('
from theistream
. - The
>>
failed, but the random byte that happened to be in the memory forc
when it was created is a'('
.
If you initialize c
to 0
, case 2 is impossible: if the operation failed, we know that c
will be 0
... so we will know for sure that if we got a '('
it's because it came from the istream
.
来源:https://stackoverflow.com/questions/30563673/what-did-the-author-mean-with-his-comment-about-the-input-of-a-user-defined-type