* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
@ 2024-01-19 7:40 ` redi at gcc dot gnu.org
2024-01-19 7:45 ` redi at gcc dot gnu.org
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 7:40 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |13.3
Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org
Ever confirmed|0 |1
Status|UNCONFIRMED |ASSIGNED
Last reconfirmed| |2024-01-19
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Hirthammer from comment #0)
> error: no match for 'operator<<' (operand types are
> 'std::__cxx11::basic_ostringstream<char>' and 'const
> std::chrono::time_point<std::chrono::_V2::system_clock,
> std::chrono::duration<float> >')
> 726 | __os << __t;
> | ~~~~~^~~~~~
> ---
>
> If you change the type def `Representation` to an integer or unsigned
> integer type, the code compiles.
Confirmed.
> Side note:
> Don't know if it helps, but the latest clang compiler version produces the
> same error. The related bug report can be found here:
>
> https://github.com/llvm/llvm-project/issues/78555
Since this is a bug in libstdc++ headers it's not at all surprising that you
get the same error with any compiler using those headers. This should not have
been reported to llvm.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
2024-01-19 7:40 ` [Bug libstdc++/113500] " redi at gcc dot gnu.org
@ 2024-01-19 7:45 ` redi at gcc dot gnu.org
2024-01-19 8:14 ` Hirthammer@allterra-dno.de
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 7:45 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Hirthammer from comment #0)
> Consider the following code snippet:
As stated at https://gcc.gnu.org/bugs we want a complete test case, not a
snippet.
#include <chrono>
#include <format>
std::chrono::sys_time<std::chrono::duration<float>> tp = {};
auto time_string = std::format("{:%S}", tp);
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
2024-01-19 7:40 ` [Bug libstdc++/113500] " redi at gcc dot gnu.org
2024-01-19 7:45 ` redi at gcc dot gnu.org
@ 2024-01-19 8:14 ` Hirthammer@allterra-dno.de
2024-01-19 11:49 ` redi at gcc dot gnu.org
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Hirthammer@allterra-dno.de @ 2024-01-19 8:14 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #3 from Hirthammer@allterra-dno.de ---
Sorry, for the missing includes.
> Since this is a bug in libstdc++ headers it's not at all surprising that you get
> the same error with any compiler using those headers. This should not have been
> reported to llvm.
Thanks for clarifying this.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (2 preceding siblings ...)
2024-01-19 8:14 ` Hirthammer@allterra-dno.de
@ 2024-01-19 11:49 ` redi at gcc dot gnu.org
2024-01-19 13:09 ` Hirthammer@allterra-dno.de
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 11:49 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
MSVC rejects this the same way, although libc++ from LLVM 17 compiles it.
AFAICT std::format("{}", tp) would be invalid because that formats tp by
writing to a stream, and there is no operator<< for
sys_time<duration<floating-point>>.
Arguably, std::format("{:%S}", tp) could work, because it doesn't need to use
operator<< but the problem is that we can't detect at compile-time whether or
not we need to use operator<< for a given format string. So it always fails to
compile.
The reason it works with libc++ is because they have a bug in their operator<<
for sys_time.
I think libstdc++ is correct here, but I've asked the C++ committee whether we
might want to change the standard to support this case.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (3 preceding siblings ...)
2024-01-19 11:49 ` redi at gcc dot gnu.org
@ 2024-01-19 13:09 ` Hirthammer@allterra-dno.de
2024-01-19 13:39 ` redi at gcc dot gnu.org
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Hirthammer@allterra-dno.de @ 2024-01-19 13:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #5 from Hirthammer@allterra-dno.de ---
(In reply to Jonathan Wakely from comment #4)
> MSVC rejects this the same way, although libc++ from LLVM 17 compiles it.
>
> AFAICT std::format("{}", tp) would be invalid because that formats tp by
> writing to a stream, and there is no operator<< for
> sys_time<duration<floating-point>>.
>
> Arguably, std::format("{:%S}", tp) could work, because it doesn't need to
> use operator<< but the problem is that we can't detect at compile-time
> whether or not we need to use operator<< for a given format string. So it
> always fails to compile.
>
> The reason it works with libc++ is because they have a bug in their
> operator<< for sys_time.
>
> I think libstdc++ is correct here, but I've asked the C++ committee whether
> we might want to change the standard to support this case.
This whole thing with std::format and std::chrono::time_point is currently a
total minefield. In MSVC it is even more complicated and I already reported the
bug in October 2023. See:
https://developercommunity.visualstudio.com/t/Using-std::format-with-unsigned-integer-/10501153
If you change the clock to utc_clock or gps_clock the code compiles with MSVC
(but not with GCC) on Compiler Explorer.
I don't know much about the exact definitions of the standard. But I find it
very confusing if std::format generally supports a std::chrono::time_point as
an input, but depending on the chosen template arguments of the time_point it
does or does not compile.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (4 preceding siblings ...)
2024-01-19 13:09 ` Hirthammer@allterra-dno.de
@ 2024-01-19 13:39 ` redi at gcc dot gnu.org
2024-01-19 13:44 ` redi at gcc dot gnu.org
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 13:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Hirthammer from comment #5)
> This whole thing with std::format and std::chrono::time_point is currently a
> total minefield.
That seems like an exaggeration.
> In MSVC it is even more complicated and I already reported
> the bug in October 2023. See:
>
> https://developercommunity.visualstudio.com/t/Using-std::format-with-
> unsigned-integer-/10501153
>
> If you change the clock to utc_clock or gps_clock the code compiles with
> MSVC (but not with GCC) on Compiler Explorer.
It compiles fine with GCC for me.
> I don't know much about the exact definitions of the standard. But I find it
> very confusing if std::format generally supports a std::chrono::time_point
> as an input, but depending on the chosen template arguments of the
> time_point it does or does not compile.
That's because operator<< is not defined in general for time_point, only for
specific clocks. It's defined for utc_time and gps_time unconditionally. It's
only defined for sys_time for non-floating-point representations and periods
less than a day:
https://en.cppreference.com/w/cpp/chrono/system_clock/operator_ltlt
Because std::format for chrono types is specified to use operator<< in some
cases, that constraint for sys_time also affects std::format.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (5 preceding siblings ...)
2024-01-19 13:39 ` redi at gcc dot gnu.org
@ 2024-01-19 13:44 ` redi at gcc dot gnu.org
2024-01-19 21:26 ` redi at gcc dot gnu.org
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 13:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #6)
> (In reply to Hirthammer from comment #5)
> > This whole thing with std::format and std::chrono::time_point is currently a
> > total minefield.
>
> That seems like an exaggeration.
>
> > In MSVC it is even more complicated and I already reported
> > the bug in October 2023. See:
> >
> > https://developercommunity.visualstudio.com/t/Using-std::format-with-
> > unsigned-integer-/10501153
> >
> > If you change the clock to utc_clock or gps_clock the code compiles with
> > MSVC (but not with GCC) on Compiler Explorer.
>
> It compiles fine with GCC for me.
Ah, maybe you mean your original example. The one at in the MSVC bug report
compiles fine with GCC using utc_clock and gps_clock.
Your original example doesn't, because formatting a utc_time or gps_time is
specified in terms of a sys_time, and that's how libstdc++ implements it. So if
the utc_time or gps_time uses a float rep, we're back to square one.
I'll ask the committee to clarify that too.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (6 preceding siblings ...)
2024-01-19 13:44 ` redi at gcc dot gnu.org
@ 2024-01-19 21:26 ` redi at gcc dot gnu.org
2024-01-21 22:25 ` cvs-commit at gcc dot gnu.org
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-19 21:26 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I am testing a patch that allows writing floating-point utc_time, gps_time etc.
with any format string, and allows writing floating-point sys_time with a
non-empty spec.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (7 preceding siblings ...)
2024-01-19 21:26 ` redi at gcc dot gnu.org
@ 2024-01-21 22:25 ` cvs-commit at gcc dot gnu.org
2024-01-21 22:27 ` redi at gcc dot gnu.org
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-21 22:25 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:
https://gcc.gnu.org/g:7431fcea6b72beb54abb1932c254ac0e76bd0bde
commit r14-8321-g7431fcea6b72beb54abb1932c254ac0e76bd0bde
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Sun Jan 21 18:16:14 2024 +0000
libstdc++: Fix std::format for floating-point chrono::time_point [PR113500]
Currently trying to use std::format with certain specializations of
std::chrono::time_point is ill-formed, due to one member function of the
__formatter_chrono type which tries to write a time_point to an ostream.
For sys_time<floating-point> or sys_time with a period greater than days
there is no operator<< that can be used.
That operator<< is only needed when using an empty chrono-specs in the
format string, like "{}", but the ill-formed expression gives an error
even if not actually used. This means it's not possible to format some
other specializations of chrono::time_point, even when using a non-empty
chrono-specs.
This fixes it by avoiding using 'os << t' for all chrono::time_point
specializations, and instead using std::format("{:L%F %T}", t). So that
we continue to reject std::format("{}", sys_time{1.0s}) a check for
empty chrono-specs is added to the formatter<sys_time<D>, C>
specialization.
While testing this I noticed that the output for %S with a
floating-point duration was incorrect, as the subseconds part was being
appended to the seconds without a decimal point, and without the correct
number of leading zeros.
libstdc++-v3/ChangeLog:
PR libstdc++/113500
* include/bits/chrono_io.h (__formatter_chrono::_M_S): Fix
printing of subseconds with floating-point rep.
(__formatter_chrono::_M_format_to_ostream): Do not write
time_point specializations directly to the ostream.
(formatter<chrono::sys_time<D>, C>::parse): Do not allow an
empty chrono-spec if the type fails to meet the constraints for
writing to an ostream with operator<<.
* testsuite/std/time/clock/file/io.cc: Check formatting
non-integral times with empty chrono-specs.
* testsuite/std/time/clock/gps/io.cc: Likewise.
* testsuite/std/time/clock/utc/io.cc: Likewise.
* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (8 preceding siblings ...)
2024-01-21 22:25 ` cvs-commit at gcc dot gnu.org
@ 2024-01-21 22:27 ` redi at gcc dot gnu.org
2024-01-22 8:37 ` Hirthammer@allterra-dno.de
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-21 22:27 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed on trunk so far.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (9 preceding siblings ...)
2024-01-21 22:27 ` redi at gcc dot gnu.org
@ 2024-01-22 8:37 ` Hirthammer@allterra-dno.de
2024-01-30 14:55 ` cvs-commit at gcc dot gnu.org
2024-01-30 15:18 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: Hirthammer@allterra-dno.de @ 2024-01-22 8:37 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #11 from Hirthammer@allterra-dno.de ---
(In reply to Jonathan Wakely from comment #7)
> (In reply to Jonathan Wakely from comment #6)
> > (In reply to Hirthammer from comment #5)
> > > This whole thing with std::format and std::chrono::time_point is currently a
> > > total minefield.
> >
> > That seems like an exaggeration.
> >
> > > In MSVC it is even more complicated and I already reported
> > > the bug in October 2023. See:
> > >
> > > https://developercommunity.visualstudio.com/t/Using-std::format-with-
> > > unsigned-integer-/10501153
> > >
> > > If you change the clock to utc_clock or gps_clock the code compiles with
> > > MSVC (but not with GCC) on Compiler Explorer.
> >
> > It compiles fine with GCC for me.
>
> Ah, maybe you mean your original example. The one at in the MSVC bug report
> compiles fine with GCC using utc_clock and gps_clock.
>
> Your original example doesn't, because formatting a utc_time or gps_time is
> specified in terms of a sys_time, and that's how libstdc++ implements it. So
> if the utc_time or gps_time uses a float rep, we're back to square one.
>
> I'll ask the committee to clarify that too.
Yes, I was referring to my original example because it helped me to understand
which combinations worked and which did not.
I wrote a wrapper class around std::chrono::time_point, because I am dealing a
lot with different time formats. I am also doing multi-platform development,
and during the testing phase, it turned out that no compiler was able to
compile all templated test cases (Clang uses libstdc++ if you do not explicitly
tell it not to do, as you pointed out on the llvm bug report). Since the error
case parameter combinations differed from MSVC and GCC, I had to use many
different compiler-specific sections to get consistent and valid behavior in
the tests. That's why I called it a minefield. Maybe it was exaggerated ;).
Anyways, thank you a lot for your effort and clarifications and especially for
the fast fix.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (10 preceding siblings ...)
2024-01-22 8:37 ` Hirthammer@allterra-dno.de
@ 2024-01-30 14:55 ` cvs-commit at gcc dot gnu.org
2024-01-30 15:18 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-30 14:55 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:
https://gcc.gnu.org/g:a5aca83ca9c7fac895d10eb7b3e14b1927ec1eac
commit r13-8263-ga5aca83ca9c7fac895d10eb7b3e14b1927ec1eac
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Sun Jan 21 18:16:14 2024 +0000
libstdc++: Fix std::format for floating-point chrono::time_point [PR113500]
Currently trying to use std::format with certain specializations of
std::chrono::time_point is ill-formed, due to one member function of the
__formatter_chrono type which tries to write a time_point to an ostream.
For sys_time<floating-point> or sys_time with a period greater than days
there is no operator<< that can be used.
That operator<< is only needed when using an empty chrono-specs in the
format string, like "{}", but the ill-formed expression gives an error
even if not actually used. This means it's not possible to format some
other specializations of chrono::time_point, even when using a non-empty
chrono-specs.
This fixes it by avoiding using 'os << t' for all chrono::time_point
specializations, and instead using std::format("{:L%F %T}", t). So that
we continue to reject std::format("{}", sys_time{1.0s}) a check for
empty chrono-specs is added to the formatter<sys_time<D>, C>
specialization.
While testing this I noticed that the output for %S with a
floating-point duration was incorrect, as the subseconds part was being
appended to the seconds without a decimal point, and without the correct
number of leading zeros.
libstdc++-v3/ChangeLog:
PR libstdc++/113500
* include/bits/chrono_io.h (__formatter_chrono::_M_S): Fix
printing of subseconds with floating-point rep.
(__formatter_chrono::_M_format_to_ostream): Do not write
time_point specializations directly to the ostream.
(formatter<chrono::sys_time<D>, C>::parse): Do not allow an
empty chrono-spec if the type fails to meet the constraints for
writing to an ostream with operator<<.
* testsuite/std/time/clock/file/io.cc: Check formatting
non-integral times with empty chrono-specs.
* testsuite/std/time/clock/gps/io.cc: Likewise.
* testsuite/std/time/clock/utc/io.cc: Likewise.
* testsuite/std/time/hh_mm_ss/io.cc: Likewise.
(cherry picked from commit 7431fcea6b72beb54abb1932c254ac0e76bd0bde)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Bug libstdc++/113500] Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<'
2024-01-19 7:11 [Bug libstdc++/113500] New: Using std::format with float or double based std::chrono::time_point causes error: no match for 'operator<<' Hirthammer@allterra-dno.de
` (11 preceding siblings ...)
2024-01-30 14:55 ` cvs-commit at gcc dot gnu.org
@ 2024-01-30 15:18 ` redi at gcc dot gnu.org
12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2024-01-30 15:18 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113500
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |FIXED
Status|ASSIGNED |RESOLVED
--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed for 13.3 now too. Thanks for the report.
^ permalink raw reply [flat|nested] 14+ messages in thread