cprintfconversion-specifier

printf: why doesn't %x print leading 0x (as opposed to %a)?


This code:

#include <stdio.h>
int main(void)
{
    printf("%a\n", 1.0);
    printf("%x\n", 93);
}

outputs:

0x1p+0
5d

Why not 0x5d?

Does someone know the rationale?

Note: this question is not exactly the same since it is about %#x.

Reason of the question: for %x cannot always "feed it back to C in initializer":

$ cat t324.c
#include <stdio.h>
int main(void)
{
    printf(X);
}

$ gcc t324.c -DX="\"double x = %a;\", 10.0" && ./a.exe | gcc -xc - -c
<nothing>

$ gcc t324.c -DX="\"int x = %x;\", 10" && ./a.exe | gcc -xc - -c
<stdin>:1:9: error: ‘a’ undeclared here (not in a function)

Solution

  • "%a", "%A" leads with "0x", "0X" to help distinguish it from decimal output of "%f", "%e", "%g", "%F", ...
    Note "%a" instead of say "%e", affect 2 parts, the prefix and the base letter: "0x" and "p" instead of "" and "e".
    "%a" came along well after memory prices dropped.

    "%x" leads without a prefix as often code needs to concatenate hex output as in printf("%08x%08x", a32, b32); It is trivial to prefix with "0x" then as in "0x%08x%08x". Not prefixing hex output as the default was certainly more common, back in the day (1970s) as every bytes costs.

    Using # with "%x" as in "%#x" does not always prefix output. The prefix occurs (in the same case as digits) when the value is non-zero.

    For clarity, I find a lower case x and uppercase hex digits useful.

    //       v------ lower --------v
    printf("0x%08X\n", 0u-1u); // 0xFFFFFFFF 
    //           ^-- upper ---------^^^^^^^^