Created on 2021-03-19.00:00:00 last changed 12 months ago
Proposed resolution:
This wording is relative to N4878.
Modify [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 duration d using the format flags given in the NTCTS fmt as specified in [time.parse].
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 valueIf the parse fails to decode a valid duration, is.setstate(ios_base::failbit) is called and d is not modified. If %Z is used and successfully parsed, that value will be assigned to *abbrev if abbrev is non-null. If %z (or a modified variant) is used and successfully parsed, that value will be assigned to *offset if offset is non-null.
[ 2021-06-07 Approved at June 2021 virtual plenary. Status changed: Voting → WP. ]
[ 2021-04-20; Reflector poll ]
Set status to Tentatively Ready after eight votes in favour during reflector poll.
The duration specialization of from_stream says in N4878 [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, [time.cal.day.nonmembers]/8:
If the parse fails to decode a valid day, is.setstate(ios_base::failbit) is called and d 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". [time.parse]/12 says that failbit should be set, but neither it nor [time.duration.io]/3 mention the duration result if parsing fails.
This has been discussed at the Microsoft STL project, where Howard Hinnant, coauthor of P0355R7 that added these functions, commented: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 if failbit 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.
Thanks to Stephan T. Lavavej, Miya Natsuhara, and Howard Hinnant for valuable investigation and discussion of this issue.History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-22 15:47:43 | admin | set | status: wp -> c++23 |
2021-06-07 16:58:04 | admin | set | messages: + msg11903 |
2021-06-07 16:58:04 | admin | set | status: voting -> wp |
2021-05-26 21:11:22 | admin | set | status: ready -> voting |
2021-04-20 20:39:33 | admin | set | messages: + msg11772 |
2021-04-20 20:39:33 | admin | set | status: new -> ready |
2021-03-20 18:54:08 | admin | set | messages: + msg11752 |
2021-03-19 00:00:00 | admin | create |