[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