This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
chrono::from_stream()
assign zero to duration
for failure?Section: 30.5.11 [time.duration.io] Status: C++23 Submitter: Matt Stephanson Opened: 2021-03-19 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [time.duration.io].
View all issues with C++23 status.
Discussion:
The duration
specialization of from_stream
says in N4878
30.5.11 [time.duration.io]/3:
If the parse parses everything specified by the parsing format flags without error, and yet none of the flags impacts a duration,
d
will be assigned a zero value.
This is in contrast to the other specializations that say, for example, 30.8.3.3 [time.cal.day.nonmembers]/8:
If the parse fails to decode a valid day,
is.setstate(ios_base::failbit)
is called andd
is not modified.
The wording ("none of the flags impacts a duration" vs. "parse fails to decode a valid [meow]") and semantics
("assigned a zero value" vs. "not modified") are different, and it's not clear why that should be so. It also
leaves unspecified what should be done in case of a parse failure, for example parsing "%j"
from a
stream containing "meow"
. 30.13 [time.parse]/12 says that failbit
should be set,
but neither it nor 30.5.11 [time.duration.io]/3 mention the duration
result if parsing fails.
This looks like a bug in the standard to me, due to two errors on my part.
I believe that the standard should clearly say that iffailbit
is set, the parsed variable (duration
,time_point
, whatever) is not modified. I mistakenly believed that the definition of unformatted input function covered this behavior. But after review, I don't believe it does. Instead each extraction operator seems to say this separately. I also at first did not have my example implementation coded to leave the duration unchanged. So that's how the wording got in in the first place. Here's the commit where I fixed my implementation: HowardHinnant/date@d53db7a. And I failed to propagate that fix into the proposal/standard.
It would be clearer and simpler for users if the from_stream
specializations were consistent in wording
and behavior.
[2021-04-20; Reflector poll]
Set status to Tentatively Ready after eight votes in favour during reflector poll.
[2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4878.
Modify 30.5.11 [time.duration.io] as indicated:
template<class charT, class traits, class Rep, class Period, class Alloc = allocator<charT>> basic_istream<charT, traits>& from_stream(basic_istream<charT, traits>& is, const charT* fmt, duration<Rep, Period>& d, basic_string<charT, traits, Alloc>* abbrev = nullptr, minutes* offset = nullptr);-3- Effects: Attempts to parse the input stream
is
into the durationd
using the format flags given in the NTCTSfmt
as specified in 30.13 [time.parse].If the parse parses everything specified by the parsing format flags without error, and yet none of the flags impacts a duration,If the parse fails to decode a valid duration,d
will be assigned a zero valueis.setstate(ios_base::failbit)
is called andd
is not modified. If%Z
is used and successfully parsed, that value will be assigned to*abbrev
ifabbrev
is non-null. If%z
(or a modified variant) is used and successfully parsed, that value will be assigned to*offset
ifoffset
is non-null.