std::print
should permit an efficient implementationSection: 31.7.10 [print.fun] Status: LEWG Submitter: Victor Zverovich Opened: 2024-01-20 Last modified: 2024-03-12
Priority: 3
View other active issues in [print.fun].
View all other issues in [print.fun].
View all issues with LEWG status.
Discussion:
std::print
/std::vprint*
is currently defined in terms of formatting into a temporary string, e.g.
31.7.10 [print.fun]:
void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);Preconditions:
Effects: Writes the result ofstream
is a valid pointer to an output C stream.vformat(fmt, args)
tostream
. Throws: Any exception thrown by the call tovformat
(28.5.3 [format.err.report]).system_error
if writing tostream
fails. May throwbad_alloc
.
This is done to make it clear that noninterleaved output is desired while keeping specification simple and portable.
Unfortunately, the current specification seems to prohibit a more efficient implementation that performs formatting directly into a stream buffer under a lock (flockfile
/funlockfile
in POSIX) like printf
does.
The difference can be observable in case of an I/O error that occurs before a custom formatter is called. In the
(double buffered) implementation that directly follows the spec all formatters will be called, while in a more efficient
(locking) implementation subsequent formatters may not be called.
The easiest fix, given in the current proposed resolution, is to say that some arguments may not be formatted in
case of a write error. It might be a bit weird considering that the spec says that we construct a string first so an
alternative resolution is to replace vformat
with vformat_to
info some unspecified buffer iterator
and state noninterleaving requirement separately.
[2024-02-19; Feb 2024 mailing]
This would be resolved by P3107.
[2024-03-12; Reflector poll]
Set priority to 3 and status to LEWG after reflector poll in January 2024.
"This loses the guarantee that if the formatting throws then there's no output."
Proposed resolution:
This wording is relative to N4971.
Modify 31.7.10 [print.fun] as indicated:
void vprint_unicode(FILE* stream, string_view fmt, format_args args);[…]-6- Preconditions:
-7- Effects: The function initializes an automatic variable viastream
is a valid pointer to an output C stream.string out = vformat(fmt, args);If
If writing to the terminal orstream
refers to a terminal capable of displaying Unicode, writes out to the terminal using the native Unicode API; if out contains invalid code units, the behavior is undefined and implementations are encouraged to diagnose it. Otherwise writesout
tostream
unchanged. If the native Unicode API is used, the function flushesstream
before writingout
.stream
fails, some arguments inargs
may not be formatted. […]void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);-11- Preconditions:
-12- Effects: Writes the result ofstream
is a valid pointer to an output C stream.vformat(fmt, args)
tostream
. If writing tostream
fails, some arguments inargs
may not be formatted. -13- Throws: […].