Hi Andre,
I understand that defining PRI*8 to "*" rather than "hh*" is not
elegant, but it is correct.
This is the relevant text from the C99 draft (7.8.1):
Each of the following object-like macros expands to a character string
literal containing a conversion specifier, possibly modified by a
length modifier, suitable for use within the format argument of a
formatted input/output function when converting the corresponding
integer type. These macro names have the general form of PRI
(character string literals for the fprintf and fwprintf family) or SCN
(character string literals for the fscanf and fwscanf family),
followed by the conversion specifier, followed by a name corresponding
to a similar type name in 7.18.1. In these names, N represents the
width of the type as described in 7.18.1. For example, PRIdFAST32 can
be used in a format string to print the value of an integer of type
int_fast32_t.
So all that is required is that the definition is suitable for use in
combination with that type. There is nothing that specifically implies
that PRI*8 needs to be "hh*".
For example, if PRId8 is defined to "d", the following code will
behave as expected. This is because x is implicitly promoted to int,
and int is the valid type to use with %d.
uint8_t x = 255; printf("%"PRId8, x);
I think that one of these three things should be done:
- Revert the changes so that PRI*8 is again defined to "*".
- Provide the new definitions ("hh*") when C99 printf is supported,
but the old ones ("*") if it's not.
- Do not define the PRI*8 macros when C99 printf is not supported.
Post by Andre VieiraI do agree that it is weird that for the SCN*8 macros to be guarded with _WANT_IO_C99_FORMATS, whilst the PRI*8 are not.
This is likely because the old PRI*8 definitions were known to be
correct regardless of C99 printf support. And the reason that the
SCN*8 macros must be guarded is because the scanf implementation needs
to specifically aware of the exact type that the passed pointers point
to, so that the outputs can be correctly stored. There is no implicit
promotion to "save us" in the case of scanf.
You might be surprised how Linux defines these macros - at least on
the machine I tested on, PRI*8 was "*".
Best
On Mon, Jan 4, 2016 at 12:21 PM, Andre Vieira
Post by Andre VieiraHi Ambroz,
Just to clarify as to why this change was made. The PRI*8 and SCN*8 macro's
were printing '*' before, the pattern for 32-bit types, when the actual size
of __INT8_TYPE__ was '8 bits', i.e. _WANT_IO_C99_FORMATS was defined. Which
we agreed at the time was the wrong behavior.
Now you are not the first to stumble onto this issue, though as FCh points
out these are C99 types and the configurations you mentioned do not support
these.
Hi Freddie,
I hope we agree that C99 support should not be an all-or-nothing
decision, you should be able to have some parts (like the stdint types
which cost nothing), but not other parts like the full C99 support in
printf. The worst part really is that the PRI*8 macros are defined in
the mentioned configurations but they do not work. I see that on the
other hand the SCN*8 macros are not defined when they would not work
(see the top comment in inttypes.h).
I do agree that it is weird that for the SCN*8 macros to be guarded with
_WANT_IO_C99_FORMATS, whilst the PRI*8 are not. Though guarding PRI*8 would
not solve your problem, as you seem to want these to be defined as '*', i.e.
defaulting to their earlier behavior of returning the 32-bit format pattern.
I would oppose doing this in all cases, since if _WANT_IO_C99_FORMATS is
defined, then this would yield the erroneous behavior this patch was meant
to fix.
There might be a case to be made for doing so if _WANT_IO_C99_FORMATS is not
defined. On the other hand, doing this for SCN*8 would be a bad idea in my
opinion and this would keep the discrepancy between PRI*8 and SCN*8.
I do not think we should encourage the use of PRI*8 and SCN*8 types if these
are not supported by the library being used. As this seems to be the case,
since _WANT_IO_C99_FORMATS is not defined, which I think would be the
appropriate macro to indicate support for such.
But then we can have the PRI*8 macros for free anyway, so why should
they be available only when printf has "hh" support?
Best regards,
Ambroz
Post by Freddie ChopinPost by Ambroz BizjakHello,
It appears to me that commit "Fix for pri and scn formats" [1] broke
the 8-bit printf format macros (PRI*8), for scenarios when newlib is
configured either with --enable-newlib-nano-formatted-io or without
--enable-newlib-io-c99-format is not used. Because the new code
defines these macros to the "hh" formats, which are not supported
then.
Is it actually a problem that PRI* macros don't work without support for C99?
After all, these are used for C99 types, so not really needed without C99...
Regards,
FCh
Further discussion is most welcome!
Cheers,
Andre