std::vprint...code_locking(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

std::vprint_nonunicode, std::vprint_nonunicode_locking β€” the C++ Standard Library functions that take your format string plus type-erased args and actually push the bytes out to a stream. Yes bestie, both of them, they're a package deal πŸŽ€

So this page lives in the C++ Standard Library manual (shoutout cppreference, we'll get to that at the end 🫢).


✨ SYNOPSIS ✨

Okay so first thing, they're Defined in header <print> β€” like, that's the whole vibe check right there πŸ“Œ

void vprint_nonunicode( std::string_view fmt, std::format_args args );        (1) (since C++23)

void vprint_nonunicode( std::FILE* stream,
                        std::string_view fmt, std::format_args args );        (2) (since C++23)

void vprint_nonunicode_locking( std::FILE* stream,
                                std::string_view fmt,
                                std::format_args args );                      (3) (since C++23)

The one-line summary: format args according to the format string fmt, and writes the result to the output stream. That's it, that's the whole function πŸ’…

Now the deets on each overload, because they are not the same and you WILL get asked about them:

  1. Equivalent to std::vprint_nonunicode(stdout, fmt, args); β€” yeah she just defaults to stdout, iconic behavior honestly.
  2. Equivalent to std::string out = std::vformat(fmt, args); std::vprint_nonunicode_locking(stream, "{}", std::make_format_args(out)); β€” look at her, formatting into a string first and then doing the locked write. Rare formatter-stringless moment ✨
  3. While holding the lock on stream, writes the character representation of formatting arguments provided by args formatted according to specifications given in fmt to stream. She's the locking one, that's literally her whole personality πŸ”’
⚠️ Okay real talk bestie, listen to me: if stream is not a valid pointer to an output C stream, the behavior is undefined. No cap. Not "probably crashes", not "gives you garbage" β€” undefined. Do not be cute with this one πŸ’€

🌸 PARAMETERS 🌸

  • stream β€” output file stream to write to. That's the C stream you're yeeting your formatted text into.
  • fmt β€” an object that represents the format string. Okay so the format string is made of:
    • ordinary characters (except { and }), which are copied unchanged to the output,
    • escape sequences {{ and }}, which are replaced with { and } respectively in the output, and
    • replacement fields.

Each replacement field has the following format:

{ arg-id (optional) }               (1)
{ arg-id (optional) : format-spec } (2)
  1. replacement field without a format specification
  2. replacement field with a format specification

And now the sub-parts, stay with me:

  • arg-id β€” specifies the index of the argument in args whose value is to be used for formatting; if it is omitted, the arguments are used in order. The arg-ids in a format string must all be present or all be omitted. Mixing manual and automatic indexing is an error. So pick a lane bestie 😀
  • format-spec β€” the format specification defined by the std::formatter specialization for the corresponding argument. Cannot start with }. That's a hard no on } at the start, fr fr.

And how format-spec gets interpreted depends on what you're formatting:

  • For basic types and standard string types, the format specification is interpreted as standard format specification.
  • For chrono types, the format specification is interpreted as chrono format specification.
  • For range types, the format specification is interpreted as range format specification.
  • For std::pair and std::tuple, the format specification is interpreted as tuple format specification.
  • For std::thread::id and std::stacktrace_entry, see thread id format specification and stacktrace entry format specification. (since C++23)
  • For std::basic_stacktrace, no format specifier is allowed. Nope. None. Zero. 🚫
  • For std::filesystem::path, see path format specification. (since C++26)
  • For other formattable types, the format specification is determined by user-defined formatter specializations. That's you, you're the main character here πŸ‘‘
  • args β€” arguments to be formatted. The type-erased little bundle of everything that's about to become text.

😭 EXCEPTIONS 😭

Like, she can absolutely throw, so be ready:

  • std::bad_alloc on allocation failure.
  • std::system_error, if writing to the stream fails.
  • Propagates any exception thrown by used formatters, e.g. std::format_error.

The last one means whatever your custom formatter does, that energy gets forwarded straight to you. No filter πŸͺž


πŸ¦‹ NOTES πŸ¦‹

Feature-test macro status check, because we love a #ifdef moment:

  • __cpp_lib_print β€” value 202207L, std (C++23), feature: Formatted output
  • __cpp_lib_print β€” value 202403L, std (C++26), feature: Formatted output with stream locking (DR23)
  • __cpp_lib_format β€” value 202207L, std (C++23), feature: Exposing std::basic_format_string

(Macro collision on __cpp_lib_print is, like, canonically fine β€” different values, different standards, different drama πŸ’…)


πŸ“ EXAMPLE πŸ“

This section is incomplete Reason: no example

Yeah. Tragic. Not me waiting for the example that never comes πŸ™ˆ This page literally has no example, so don't go looking for one.


🧚 SEE ALSO 🧚

  • vprint_unicode, (C++23) β€” prints to Unicode capable stdout or a file stream using type-erased argument representation (function)
  • vprint_unicode_locking, (C++23) β€” the locking sibling of the above, same deal, also a function
  • vprint_nonunicode(std::ostream), (C++23) β€” outputs character data using type-erased argument representation (function)
  • print, (C++23) β€” prints to stdout or a file stream using formatted representation of the arguments (function template)
  • format, (C++20) β€” stores formatted representation of the arguments in a new string (function template)

πŸŽ€ CATEGORY πŸŽ€

  • Todo no example

(Yes, same energy as the Example section. She's consistent πŸ’€)


Okay that's the whole page bestie, go format something and remember to lock 🫢

Source: cppreference.com β€” page version/date 2024.06.10 β€” original header std::vprint...code_locking(3), straight from the C++ Standard Libary section of the manual πŸ’œ

πŸ“¦ where this page comes from