Skip to content

Ignore '+' and space flags for unsigned printf conversions - #4977

Open
fhgffy wants to merge 1 commit into
fmtlib:mainfrom
fhgffy:fix-printf-unsigned-sign
Open

fhgffy wants to merge 1 commit into
fmtlib:mainfrom
fhgffy:fix-printf-unsigned-sign

Conversation

@fhgffy

@fhgffy fhgffy commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

fmt::sprintf applies the '+' and space flags to unsigned conversions, while C only applies them to signed ones (d, i, and the floating-point conversions):

std::printf("%+u", 42);        // 42
fmt::sprintf("%+u", 42);       // +42
fmt::sprintf("% x", 42);       // " 2a", printf gives "2a"
fmt::sprintf("%+#06x", 42);    // "+0x02a", printf gives "0x002a"

This drops the sign for u, o, x and X before the type is normalized. %c, %s and the signed conversions are unchanged.

I added cases to the plus_flag and space_flag tests; they fail without the change and the full test suite passes with it. I also compared fmt::sprintf against glibc snprintf over a few hundred thousand random flag/width/precision combinations for d/i/o/u/x/X/c, and with this change the integer conversions all match.

C only applies the '+' and space flags to signed conversions, so
fmt::sprintf("%+u", 42) should give "42" like printf does, not "+42".
The same goes for %o, %x and %X.
@fhgffy
fhgffy requested a review from vitaut as a code owner October 8, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant