Skip to content

Removed default '#' from %p#293

Closed
stefano-zanotti-88 wants to merge 1 commit into
charlesnicholson:mainfrom
stefano-zanotti-88:optional-hash-for-p
Closed

Removed default '#' from %p#293
stefano-zanotti-88 wants to merge 1 commit into
charlesnicholson:mainfrom
stefano-zanotti-88:optional-hash-for-p

Conversation

@stefano-zanotti-88

@stefano-zanotti-88 stefano-zanotti-88 commented May 3, 2025

Copy link
Copy Markdown
Contributor

%p is implementation-defined, so the current implementation is fine.
However, it introduces a default '#'. This is present in other implementations as well, though not all of them.
%p respects width and precision specifiers, as well as flags. [edit: currently, %p explicitly ignores the precision: out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE]
So, it seems inconsistent that it should not respect the presence/absence of '#'.

Before vs after this change:

printf("%p"     , NULL);     // "0x0"          vs "0"
printf("%#p"    , NULL);     // "0x0"          vs "0"
printf("%10p"   , NULL);     // "       0x0"   vs "         0"
printf("%#10p"  , NULL);     // "       0x0"   vs "         0"
printf("%010p"  , NULL);     // "0x00000000"   vs "0000000000"
printf("%#010p" , NULL);     // "0x00000000"   vs "0000000000"
printf("%.10p"  , NULL);     // "0x0000000000" vs "0000000000"
printf("%#.10p" , NULL);     // "0x0000000000" vs "0000000000"
printf("%0.10p" , NULL);     // "0x0000000000" vs "0000000000"
printf("%#0.10p", NULL);     // "0x0000000000" vs "0000000000"
printf("%p"     , (void*)1); // "0x1"          vs "1"
printf("%#p"    , (void*)1); // "0x1"          vs "0x1"
printf("%10p"   , (void*)1); // "       0x1"   vs "         1"
printf("%#10p"  , (void*)1); // "       0x1"   vs "       0x1"
printf("%010p"  , (void*)1); // "0x00000001"   vs "0000000001"
printf("%#010p" , (void*)1); // "0x00000001"   vs "0x00000001"
printf("%.10p"  , (void*)1); // "0x0000000001" vs "0000000001"
printf("%#.10p" , (void*)1); // "0x0000000001" vs "0x0000000001"
printf("%0.10p" , (void*)1); // "0x0000000001" vs "0000000001"
printf("%#0.10p", (void*)1); // "0x0000000001" vs "0x0000000001"

You could argue that with this change, %p is mostly useless, as it is equivalent to %x with appropriate parameters; however, that's mostly true in any case, and the major benefit of %p is that you don't need a cast to the appropriate integer type (like casting to uintptr_t and using %tx, or casting to (unsigned long) and using %lx, or something else, depending on your platform).

Indeed, it could be easier just to change line 914 from:

need_0x = 'x';

to

if (fs.alt_form) { need_0x = 'x'; }

Note that this, just like the current behavior, always adds "0x", whereas the "%x" equivalent proposed in this change omits it when the number is 0 (a very weird corner case required by the standard).

I'd say it could be more logical, and also result in smaller code, to apply the one-line change instead.
Also, this would allow for an easier removal of %p support, which would reduce the code footprint. I'm sure that not everybody has a need for %p.

Also note: if '#' is made optional here, and you accept #288 (making '#'-support optional for NPF), then further work would be needed to completely remove the 'need_0x' logic when '#'-support is disabled.

@charlesnicholson

Copy link
Copy Markdown
Owner

This is very insightful and IMO a nice improvement to the code size- if users really want %p to add the 0x, they can add the # themselves.

I'm happy to merge this but the tests need some updating. I also think your other proposal in #288 is good so I think there's now an ordering issue. What order would you like to proceed in for these PRs?

@stefano-zanotti-88

Copy link
Copy Markdown
Contributor Author

I'd go with #288 first.
I'll fix the tests.
Let me know which route you like best: the single-line change, or the actual content of the PR, or something else.

@charlesnicholson

Copy link
Copy Markdown
Owner

Implemented as #305 - thanks for the PR!

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.

3 participants