Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++11 status.

696.istream::operator>>(int&) broken

Section: 31.7.5.3.2[istream.formatted.arithmetic]Status:C++11Submitter: Martin SeborOpened: 2007-06-23Last modified: 2016-01-28

Priority:Not Prioritized

View all otherissues in [istream.formatted.arithmetic].

View all issues withC++11 status.

Discussion:

From message c++std-lib-17897:

The code shown in 31.7.5.3.2[istream.formatted.arithmetic] as the "as if"implementation of the two arithmetic extractors that don't have acorrespondingnum_get interface (i.e., theshort andint overloads) is subtly buggy inhow it deals withEOF, overflow, and other similarconditions (in addition to containing a few typos).

One problem is that ifnum_get::get() reaches the EOFafter reading in an otherwise valid value that exceeds the limits ofthe narrower type (but notLONG_MIN orLONG_MAX), it will seterr toeofbit. Because of the if condition testing for(err == 0), the extractor won't setfailbit (and presumably, return a bogus value to thecaller).

Another problem with the code is that it never actually sets theargument to the extracted value. It can't happen after the call tosetstate() since the function may throw, so we need toshow when and how it's done (we can't just punt as say: "it happensafterwards"). However, it turns out that showing how it's done isn'tquite so easy since the argument is normally left unchanged by thefacet on error except when the error is due to a misplaced thousandsseparator, which causesfailbit to be set but doesn'tprevent the facet from storing the value.

[Batavia (2009-05):]

We believe this part of the Standard has been recently adjustedand that this issue was addressed during that rewrite.

Move to NAD.

[2009-05-28 Howard adds:]

I've moved this issue from Tentatively NAD to Open.

The current wording ofN2857in 28.3.4.3.2.3[facet.num.get.virtuals] p3, stage 3 appears to indicate thatin parsing arithmetic types, the value is always set, but sometimes in additionto settingfailbit.

However there is a contradictory sentence in 28.3.4.3.2.3[facet.num.get.virtuals] p1.

31.7.5.3.2[istream.formatted.arithmetic] should mimic the behavior of 28.3.4.3.2.3[facet.num.get.virtuals](whatever we decide that behavior is) forint andshort, and currently does not. I believe that thecorrect code fragment should look like:

typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;iostate err = ios_base::goodbit;long lval;use_facet<numget>(loc).get(*this, 0, *this, err, lval);if (lval < numeric_limits<int>::min()){  err |= ios_base::failbit;  val = numeric_limits<int>::min();}else if (lval > numeric_limits<int>::max()){  err |= ios_base::failbit;  val = numeric_limits<int>::max();}else  val = static_cast<int>(lval);setstate(err);

[2009-07 Frankfurt]

Move to Ready.

Proposed resolution:

Change 28.3.4.3.2.3[facet.num.get.virtuals], p1:

-1-Effects: Reads characters fromin, interpreting themaccording tostr.flags(),use_facet<ctype<charT>>(loc), anduse_facet< numpunct<charT>>(loc), whereloc isstr.getloc().If an erroroccurs,val is unchanged; otherwise it is set to the resulting value.

Change 31.7.5.3.2[istream.formatted.arithmetic], p2 and p3:

operator>>(short& val);

-2- The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment):

typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;iostate err = iostate_base::goodbit;long lval;use_facet<numget>(loc).get(*this, 0, *this, err, lval);if (err != 0)  ;else if (lval < numeric_limits<short>::min()  || numeric_limits<short>::max() < lval)     err = ios_base::failbit;if (lval < numeric_limits<short>::min()){  err |= ios_base::failbit;  val = numeric_limits<short>::min();}else if (lval > numeric_limits<short>::max()){  err |= ios_base::failbit;  val = numeric_limits<short>::max();}else  val = static_cast<short>(lval);setstate(err);
operator>>(int& val);

-3- The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment):

typedef num_get<charT,istreambuf_iterator<charT,traits> > numget;iostate err = iostate_base::goodbit;long lval;use_facet<numget>(loc).get(*this, 0, *this, err, lval);if (err != 0)  ;else if (lval < numeric_limits<int>::min()  || numeric_limits<int>::max() < lval)     err = ios_base::failbit;if (lval < numeric_limits<int>::min()){  err |= ios_base::failbit;  val = numeric_limits<int>::min();}else if (lval > numeric_limits<int>::max()){  err |= ios_base::failbit;  val = numeric_limits<int>::max();}else  val = static_cast<int>(lval);setstate(err);

[8]ページ先頭

©2009-2026 Movatter.jp