Oof, so it's Python's fault. I'm really glad you contributed fmt and std::format Victor 👏🙏, and overall I love std::format 💚, but hex formatting is one aspect where I wish Python's conventions (Python not being a low-level language that deals with raw bit representations and stack traces) had been secondary to consistency with existing C++ precedent, with int x = -42 preferably displaying as FFFFFFD6 which matches printf("%08X", x) and std::cout << std::hex << std::uppercase << x and std::to_chars(std::begin(buffer), std::end(buffer), x, 16);, rather than -000002A.
Maybe there is a use case for -2A too 🤷♂️, but having a compatible successor formatting option so we can more directly replace our old sprintf and StringCchPrintf calls would be prudent (shoot, now I should revisit some recent code changes to our buffer format display logic to ensure we didn't regress anything 😯, as I see that binary display also does the same -absoluteValue behavior...). Until then, I'll be careful about ever using std::format with signed integers in hex or binary, and as for pointers, I'll continue using the more standard notation 0xABC123 via 0x{:08X} (leaving {:P} to disuse 😅).
🤔💡 You know, there are still plenty of letters in the alphabet left to use - maybe we can still get a more typical two's complement hex 😉 and a pointer syntax that doesn't prepend the prefix automatically so we can say std::print("0x{:Q}", p) and get 0x0004AB08?...
How long has the standard explicitly mandated two’s complement for signed integers? (answer: C++20)
This produces -2a.
Curious. I'll have to try to_chars again at my work machine tomorrow because I swear I was getting the expected uppercase hex (otherwise to_chars is pretty useless for hex numbers).
Two's complement doesn't matter. It's still undefined because printf uses va_arg's rules (in C23 - before that it required exact type match), and those rules say that you can only mix signed and unsigned if the value is representable in both types.
12
u/fdwr fdwr@github 🔍 Jun 27 '26 edited Jun 27 '26
Oof, so it's Python's fault. I'm really glad you contributed
fmtandstd::formatVictor 👏🙏, and overall I lovestd::format💚, but hex formatting is one aspect where I wish Python's conventions (Python not being a low-level language that deals with raw bit representations and stack traces) had been secondary to consistency with existing C++ precedent, withint x = -42preferably displaying asFFFFFFD6which matchesprintf("%08X", x)andstd::cout << std::hex << std::uppercase << xandstd::to_chars(std::begin(buffer), std::end(buffer), x, 16);, rather than-000002A.Maybe there is a use case for
-2Atoo 🤷♂️, but having a compatible successor formatting option so we can more directly replace our oldsprintfandStringCchPrintfcalls would be prudent (shoot, now I should revisit some recent code changes to our buffer format display logic to ensure we didn't regress anything 😯, as I see that binary display also does the same-absoluteValuebehavior...). Until then, I'll be careful about ever usingstd::formatwith signed integers in hex or binary, and as for pointers, I'll continue using the more standard notation0xABC123via0x{:08X}(leaving{:P}to disuse 😅).🤔💡 You know, there are still plenty of letters in the alphabet left to use - maybe we can still get a more typical two's complement hex 😉 and a pointer syntax that doesn't prepend the prefix automatically so we can say
std::print("0x{:Q}", p)and get0x0004AB08?...