Title
num_get not fully compatible with strto*
Status
c++17
Section
[facet.num.get.virtuals]
Submitter
Cosmin Truta

Created on 2009-07-04.00:00:00 last changed 90 months ago

Messages

Date: 2015-05-22.20:19:09

Proposed resolution:

Change [facet.num.get.virtuals] as follows:

Stage 3: The sequence of chars accumulated in stage 2 (the field) is converted to a numeric value by the rules of one of the functions declared in the header <cstdlib>:

  • For a signed integer value, the function strtoll.
  • For an unsigned integer value, the function strtoull.
  • For a float value, the function strtof.
  • For a double value, the function strtod.
  • For a floating-point long double value, the function strtold.

The numeric value to be stored can be one of:

  • zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned to err.
  • the most positive (or negative) representable value, if the field to be converted to a signed integer type represents a value too large positive (or negative) to be represented in val. ios_base::failbit is assigned to err.
  • the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.
  • the most positive representable value, if the field to be converted to an unsigned integer type represents a value that cannot be represented in val.
  • the converted value, otherwise.

The resultant numeric value is stored in val. If the conversion function fails to convert the entire field, or if the field represents a value outside the range of representable values, ios_base::failbit is assigned to err.

Date: 2015-05-06.00:00:00

[ 2015-05-06 Lenexa: Move to Ready ]

STL: I like that this uses strtof, which I think is new in C99. that avoids truncation from using atof. I have another issue ...

MC: yes LWG 2403 (stof should call strtof)

PJP: the last line is horrible, you don't assign to err, you call setstate(ios_base::failbit). Ah, no, this is inside num_get so the caller does the setstate.

MC: we need all these words. are they the right words?

JW: I'd like to take a minute to check my impl. Technically this implies a change in behaviour (from always using strtold and checking the extracted floating point value, to using the right function). Oh, we already do exactly this.

MC: Move to Ready

6 in favor, none opposed, 1 abstention

Date: 2012-02-27.20:05:44

[ 2012,Kona ]

Move to Open.

THe issues is what to do with -1. Should it match 'C' or do the "sane" thing. A fix here changes behavior, but is probably what we want.

Pablo to provide wording, with help from Howard.

Date: 2011-08-18.11:49:59

[ 2011 Bloomington ]

The proposed wording looks good, no-one sure why this was held back before. Move to Review.

Date: 2011-03-24.00:00:00

[ 2011-03-24 Madrid meeting ]

Move to deferred

Date: 2010-10-21.19:00:35

[ 2010 Rapperswil: ]

Some concern that this is changing the specification for an existing C++03 function, but it was pointed out that this was underspecified as resolved by issue 23. This is clean-up for that issue in turn. Some concern that we are trying to solve the same problem in both clause 22 and 27.

Bill: There's a change here as to whether val is stored to in an error case.

Pablo: Don't think this changes whether val is stored to or not, but changes the value that is stored.

Bill: Remembers having skirmishes with customers and testers as to whether val is stored to, and the resolution was not to store in error cases.

Howard: Believes since C++03 we made a change to always store in overflow.

Everyone took some time to review the issue.

Pablo: C++98 definitely did not store any value during an error condition.

Dietmar: Depends on the question of what is considered an error, and whether overflow is an error or not, which was the crux of LWG 23.

Pablo: Yes, but given the "zero, if the conversion function fails to convert the entire field", we are requiring every error condition to store.

Bill: When did this happen?

Alisdair: One of the last two or three meetings.

Dietmar: To store a value in case of failure is a very bad idea.

Move to Open, needs more study.

Date: 2013-01-25.00:32:44

As specified in the latest draft, N2914, num_get is still not fully compatible with the following C functions: strtoul, strtoull, strtof and strtod.

In C, when conversion of a string to an unsigned integer type falls outside the representable range, strtoul and strtoull return ULONG_MAX and ULLONG_MAX, respectively, regardless whether the input field represents a positive or a negative value. On the other hand, the result of num_get conversion of negative values to unsigned integer types is zero. This raises a compatibility issue.

Moreover, in C, when conversion of a string to a floating-point type falls outside the representable range, strtof, strtod and strtold return ±HUGE_VALF, ±HUGE_VAL and ±HUGE_VALL, respectively. On the other hand, the result of num_get conversion of such out-of-range floating-point values results in the most positive/negative representable value. Although many C library implementations do implement HUGE_VAL (etc.) as the highest representable (which is, usually, the infinity), this isn't required by the C standard. The C library specification makes no statement regarding the value of HUGE_VAL and friends, which potentially raises the same compatibility issue as in the above case of unsigned integers. In addition, neither C nor C++ define symbolic constants for the maximum representable floating-point values (they only do so only for the maximum representable finite floating-point values), which raises a usability issue (it would be hard for the programmer to check the result of num_get against overflow).

As such, we propose to adjust the specification of num_get to closely follow the behavior of all of its underlying C functions.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2015-10-27 16:52:45adminsetstatus: ready -> wp
2015-05-22 20:19:09adminsetmessages: + msg7452
2015-05-22 20:19:09adminsetstatus: open -> ready
2012-02-27 20:05:44adminsetmessages: + msg6036
2012-02-27 20:05:44adminsetstatus: review -> open
2011-08-18 11:49:59adminsetmessages: + msg5863
2011-08-18 11:49:59adminsetstatus: deferred -> review
2011-03-24 15:58:06adminsetmessages: + msg5673
2011-03-24 15:58:06adminsetstatus: open -> deferred
2010-10-21 19:00:35adminsetmessages: + msg4746
2010-10-21 19:00:35adminsetstatus: new -> open
2010-10-21 18:28:33adminsetmessages: + msg993
2009-07-04 00:00:00admincreate