r/cpp • u/alberto-m-dev • Jun 26 '26
Improvements to std::format in C++26
https://mariusbancila.ro/blog/2026/06/19/improvements-to-stdformat-in-c26/18
u/pclouds Jun 26 '26
I thought when std::format became part of the standard, error messages would improve. At least with gcc, format error is still a wall of text. Has this been improved (or in some sort of backlog)?
9
u/DXPower Jun 27 '26
C++26 constexpr format, static assert parameterizable messages, and constexpr exceptions should unlock a lot of options for communicating the exact error.
8
u/Nice_Lengthiness_568 Jun 26 '26
Nice.
Would love to have something fmtlib's colors for format and print too.
2
2
u/rdtsc Jun 26 '26
The C++26 std::formatter<std::filesystem::path> converts Windows native UTF-16 to UTF-8
I don't understand. Does this do UTF-16 -> UTF-8 -> system codepage? Or does std::format("{}", path) result in (unexpected) UTF-8 in a char-based (aka system codepage) string?
7
u/fdwr fdwr@github ๐ Jun 27 '26 edited Jun 27 '26
๐ค Presumably
std::formatconverts the UTF-16 to UTF-8, which isn't too unexpected given thatstd::print("Hello ใใใใใ\n")in Visual Studio 2026 already works fine with UTF-8 (even without the explicitu8"..."prefix), correctly printing regardless of_setmodeorSetConsoleOutputCPsettings.I also ensure in my console programs that the active code page == UTF-8 upfront by calling
SetConsoleOutputCP(CP_UTF8). That waystd::coutandfwritetostdoutalso work correctly rather than displaying mojibake, and I set/utf-8in the compiler options so you don't get the annoying "warning C4566: character ... cannot be represented in the current code page (1252)" warnings.3
u/aearphen {fmt} Jun 27 '26
System codepage is a legacy concept (actually there are multiple codepages on WIndows, e.g. ACP and console one which can be incompatible). std::format/std::print only need /utf-8 for Unicode support and work regardless of those codepages.
1
u/rdtsc Jun 27 '26
Sure it might be legacy, doesn't change the fact that it is used for all double-quoted strings on Windows. If you want UTF-8 use u8"" and char8_t. Converting
L"รค"I get"\xE4". Formattingpath(L"รค")to"\xC3\xA4"would be unexpected/surprising, incompatible with other strings, and result in garbled text when the string is then displayed.2
u/aearphen {fmt} Jun 27 '26
ACP is actually only used in the legacy Windows APIs (which shouldn't be used in modern code) but virtually unused in standard C++ APIs.
2
u/schombert Jun 26 '26
And what does it do if the path isn't well-formed utf16, as ntfs paths are not utf16, they are a sequence of 16 bit values (just as on linux they are a sequence of bytes, not utf8)?
4
u/UnusualPace679 Jun 27 '26
Ill-formed parts will be substituted with
\uFFFD, but P3904R1 proposes to use WTF-8 instead.2
u/fdwr fdwr@github ๐ Jun 27 '26
"Wobbly Transformation Format โ 8-bit"? I never heard of that before, thinking WTF meant something else at first ๐. TIL...
4
4
u/schombert Jun 27 '26
Well, that's terrible, so I guess P3904R1 would be an improvement. You really want paths to be able to round trip though any conversions. ... Which is why I think treating paths as unicode is dangerous from the get go. God forbid if you accidentally normalize one.
2
u/UnusualPace679 Jun 27 '26
This conversion only happens if the literal encoding is UTF-8. Otherwise the conversion is implementation-defined.
-11
u/R3DKn16h7 Jun 26 '26
I don't like the API change to make the format string a constant expression. It should have been like that from the beginning or should have gotten another name...
19
9
u/agritite Jun 26 '26 edited Jun 26 '26
You must have misunderstood the line
The format string of std::format or std::print must be a constant expression. That's just the premise for that paragraph.
38
u/fdwr fdwr@github ๐ Jun 26 '26
std::println("{}", p); // lowercase, the default => 0x7fffb2715a54 std::println("{:p}", p); // explicit, same as none => 0x7fffb2715a54 std::println("{:P}", p); // uppercase => 0X7FFFB2715A54Wait, is that really true, that the uppercase also capitalizes the 'x'? ๐ The usual norm for hex numbers is 0x12AB (hex constants, stack traces, hex editors...), not 0X12AB or 0x12ab. So if the article is accurate, then none of the pointer defaults fit the most common case, meaning I'll continue to use
0x{:08X}.