- Title
- num_get overflow determination unclear and incorrect
- Status
- new
- Section
- [facet.num.get.virtuals]
- Submitter
- Hubert Tong

Created on **2022-03-28.00:00:00**
last changed **6 months ago**

Date: 2022-05-15.00:00:00

*[ 2022-05-17; Reflector poll ]*

Set priority to 3 after reflector poll.

Date: 2022-04-04.15:57:03

[facet.num.get.virtuals] stage 3 specifies that "by the rules of" various `strto*` functions,
sequences of chars are converted to a numeric value (producing the "converted value" that is referred to).

It then goes on to specify various error cases when the "field represents a value" that is outside the range
of representable values. Clearly, the value that would be returned from the appropriate `strto*` function
is not outside the range of representable values for `long long`, `unsigned long long`, `float`,
`double`, and `long double`; therefore (unless if we expect no range-related errors for those types),
the field "represents a value" other than the "converted value".

Issue 1: It is too subtle to have two distinct values without calling more attention to them by giving them names aside from the prose descriptions.

If the field "represents" a value other than the value that would be returned from the appropriate `strto*`
function, then what value does the field "represent"?
Note that, strictly speaking, it is the process that results in the converted value that the wording says is obtained
"by the rules of" the `strto*` functions, which is not the same thing as saying that the value represented is
interpreted "by the rules of" the `strto*` functions.

If the field "represents" the mathematical value, then for unsigned integer types, all negative values cannot be represented. This does not match existing practice.

If negative integer values are interpreted using the rules of the `strto*` functions by obtaining the
magnitude and then having it "negated (in the return type)", then the return type of `strtoull` is
`unsigned long long`, meaning (where `unsigned long long` is 64-bit) that "`-18446744073709551615`"
is `1` (even when converting to unsigned integer types of less width). That does not match existing practice.
It is also worth noting that negating in the return type does not work well if the magnitude is not representable as
a positive value in the return type (e.g., for signed integer types and their most negative representable values).

Issue 2: The effect of the minus sign with respect to unsigned integer types can reasonably be interpreted in ways
that do not match existing practice (and are presumably unintended). The interpretation that works better for
`unsigned long long` does not work as well for `signed long long`.

If the field does not "represent" the mathematical value, then for floating-point types, it is unclear whether the minus sign takes effect before or after any possible rounding. For literals, the minus sign takes effect after rounding.

Issue 3: The effect of the minus sign with respect to floating-point types is unclear.

Lastly, for floating-point types with signed infinities, there are no finite values outside the range of representable values; therefore, conversions of all finite values to such types are specified to "succeed". That does not match existing implementation practice.

Issue 4: The conditions for identifying range-related errors for conversions to floating-point types do not match the conditions that constitute overflow for floating-point types. There is implementation divergence: libc++ appears to check for floating-point overflow; libstdc++ appears to check for infinities.

History | |||
---|---|---|---|

Date | User | Action | Args |

2022-05-17 11:58:16 | admin | set | messages: + msg12462 |

2022-03-28 00:00:00 | admin | create |