https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123078
--- Comment #11 from Jan Schultke <janschultke at googlemail dot com> --- (In reply to Jonathan Wakely from comment #10) > (In reply to Jan Schultke from comment #9) > > Even if one interpreted "range of representable values" as only > > including finite values, > > As I said in the issue, and as I quoted above, -1000 is outside the range > of possible exponents for float. It has nothing to do with only including > finite values, nobody has suggested that. There is no wording that would suggest that the range of exponents lets an implementation reject from_chars inputs rather than ranges of values. > The current standard seems very clear that if ec is set in the result, then > value is not modified: > > "If the parsed value is not in the range representable by the type of value, > value is unmodified and the member ec of the return value is equal to > errc::result_out_of_range. Otherwise, value is set to the parsed value" > > Since libstdc++ is setting ec, it's correct to not modify the value. Your > example is wrong because it fails to check the result for an error. > > What's under dispute is when ec should be set. Libstdc++ currently takes the > interpretation that if strtod sets ERANGE, then from_chars sets > errc::out_of_range. That doesn't seem indefensible to me. It is implementation-defined whether strtod sets ERANGE in the case of underflow, and what it does in general. So it's not even clear whether it does, and I'm not sure what implementations do in practice here. In any case, it's indefensible because we don't have a shred of wording that would suggest that you can just set ec because a value is too small. strtod is only used as a way to define the input format in [charconv], not as a way to define how the result is determined. > As I said in comment 4, the proposed resolution of 3081 might be a better > approach. Interpreting 1e-1000 as within the representable range (as MSVC > and libc++ could be doing) might also be a better approach. But libstdc++ > follows strtof/strtod/strtolf and sets errc::out_of_range in ec. And if > that's done, then the value must be unmodified. > > If the libstdc++ interpretation should not be allowed, the standard should > be clarified. Which is LWG 3081. The standard is already perfectly clear. See [basic.fundamental] paragraph 13: > The minimum range of representable values for a floating-point type is > the most negative finite floating-point number representable in that type > through > the most positive finite floating-point number representable in that type. > In addition, if negative infinity is representable in a type, > the range of that type is extended to all negative real numbers; > likewise, if positive infinity is representable in a type, > the range of that type is extended to all positive real numbers. Mabye LWG 3081 should be closed as NAD because the wording is perfectly clear on std::from_chars being required to accept both underflow and overflow with this definition: It doesn't matter how large the exponent is, the scaled value is still a real number. It would be a breaking change if std::from_chars was setting ec and rejecting inputs on overflow or underflow, so this is an obviously evolutionary change in design direction. Of course, CWG never discussed the impact on any surrounding wording when they copied the definition of "range of representable values" from C into C++ in 2023, so the current design is arguably unintentional. > Currently the standard requires us to either report success but with an > inaccurate number, or report failure with no number at all. As 3081 says, > strtod is different, it allows reporting ERANGE *and* returning a value on > overflow and underflow. > > You can argue all you like, but there's an open issue on **exactly** this > topic, and I don't plan to change libstdc++ until it's clear how that issue > will be resolved, so that we don't have to change it twice. LWG 3081 was opened before there existed a definition of "range of representable values". The definition is now clear; it was added by CWG 2723 shortly after LWG 3081 was opened. However, LWG 3081 seems to be unaware of those recent core wording changes. Given that the wording is now perfectly clear, I don't see any reason for CWG 3081 to remain open. In any case, whether LWG 3081 is accepted or closed as NAD, there was never any wording that would suggest that underflow results in ec being set. What libstdc++ does is clearly non-compliant and arbitrary. You've only drawn a parallel to strtod, but the way that the value is determined, or the cases where inputs are rejected, are not worded in terms of strtod anyway.
