[newlib] print formats for FAST and LEAST types
Andre Vieira
Andre.SimoesDiasVieira@arm.com
Fri Jul 17 15:50:00 GMT 2015
On 14/07/15 15:57, Corinna Vinschen wrote:
> On Jul 14 15:34, Andre Vieira wrote:
>> On 14/07/15 15:18, Corinna Vinschen wrote:
>>> On Jul 14 15:08, Andre Vieira wrote:
>>>> On 14/07/15 14:49, Corinna Vinschen wrote:
>>>>> I just checked this on 32 bit Cygwin:
>>>>>
>>>>> $ gcc -E - <<EOF
>>>>> #include <inttypes.h>
>>>>> #include <stdint.h>
>>>>> __INT_FAST32_TYPE__
>>>>> PRIdFAST32
>>>>> EOF
>>>>> [...]
>>>>> int
>>>>> "d"
>>>>>
>>>>> If there's still anything wrong with that, feel free to send patches.
>>>>>
>>>>>
>>>>> Corinna
>>>>>
>>>>
>>>> Hi Corinna,
>>>>
>>>> I am on a newer version than the linked patch.
>>>>
>>>> However when I run your example I get int and "ld".
>>>> In your example, if you pass -dM, does it show INT32_EQ_LONG to be defined?
>>>
>>> No, it's undefined. This is i686-pc-cygwin. Please have a look at
>>> libc/include/sys/_intsup.h and try to find out why this doesn't work
>>> for your target.
>>>
>>>
>>> Thanks,
>>> Corinna
>>>
>>
>> Hi Corinna,
>>
>> It doesn't work because PRIdFAST32 uses __PRI32(d) as a definition and in
>> the patch you mentioned earlier __PRI32(d) is defined as "ld" if
>> _INT32_EQ_LONG is defined.
>>
>> However __INT_FAST32_TYPE__ is a builtin defined in '<GCC
>> SRC>/gcc/c-family/c-common.c' using INT_FAST32_TYPE, which is defined in
>> '<GCC SRC>/gcc/config/newlib-stdint.h' as:
>> #define INT_FAST32_TYPE (INT_TYPE_SIZE >= 32 ? "int" : INT_LEAST32_TYPE)
>>
>> So if INT_TYPE_SIZE == LONG_TYPE_SIZE, int_fast32_t will be 'int' and
>> PRIdFAST32 will yield "ld" and printf won't like that.
>
> Your analysis is missing something. Have another look at the check in
> libc/include/sys/_intsup.h:
>
> [...]
> #undef signed
> #undef int
> #undef long
> #define signed +0
> #define int +0
> #define long +1
> [...]
> #if __INT32_TYPE__ == 1
> #define _INT32_EQ_LONG
> #elif __INT32_TYPE__ == 0
> /* Nothing to define because int32_t is safe to print as an int. */
> #else
> #error "Unable to determine type definition of int32_t"
> #endif
> #undef long
> #undef int
> #undef signed
> [...]
>
> __INT32_TYPE__ is defined by GCC as well. If __INT_FAST32_TYPE__ is
> int, then why is __INT32_TYPE__ long? And if that's the right thing to
> do, we need a patch to sys/_intsup.h to apply the same check to
> __INT_FAST32_TYPE__ and use that to define __PRI32fast and __SCN32fast
> macros.
>
>
> Corinna
>
Hi Corinna,
Thank you for your quick replies!
I don’t know whether the current behavior of assigning INT32_TYPE and
INT_FAST32_TYPE the types "long" and "int" respectively given
INT_TYPE_SIZE = LONG_TYPE_SIZE = 32, is the right thing to do. Might be
worth bringing it up with someone, maybe the gcc mailing list?
However, as is, _intsup.h and inttypes.h don’t reflect these
discrepancies and we could use the same approach as was used with
_INT32_EQ_LONG to mend that.
Also Kevin brought to our attention that inttypes.h is riddled with the
assumption that intNN_t == int_fastNN_t == int_leastNN_t.
For instance, on my system SCNdFAST8 will yield 'hhd' whereas
INT_FAST8_TYPE is 'int'. All other PRIdFAST8, PRId8 and PRIdLEAST8 will
be 'd'. Not entirely sure this is expected behaviour or not. What is
your opinion on this?
Might be also good to point out that printf only seems to warn against
using formats that may represent larger integers than the ones passed as
arguments.
Kind Regards,
Andre Vieira
More information about the Newlib
mailing list