printf/inttypes.h warning

Joel Sherrill
Tue Dec 16 00:55:00 GMT 2014

On 12/15/2014 2:13 PM, Corinna Vinschen wrote:
> On Dec 15 12:10, Joel Sherrill wrote:
>> On 12/15/2014 9:14 AM, Corinna Vinschen wrote:
>>> Hi Joel,
>>> On Dec 14 23:19, Joel Sherrill wrote:
>>>> Hi
>>>> I haven't investigated which other targets have this inconsistency yet.
>>>> But the following code gives a printf format warning on i386-rtems but not
>>>> on sparc-rtems.
>>>> #include <stdint.h>
>>>> #include <inttypes.h>
>>>> #include <stdio.h>
>>>> void f(uintptr_t me)
>>>> {
>>>>   printf( "A: %" PRIdPTR " B: %" PRIdPTR "\n", me, 1 - me );
>>>> }
>>>> This is because intptr_t and uintptr_t are defined as just unsigned int
>>>> on sparc but long unsigned int on i386. 
>>>> $ sparc-rtems4.11-gcc -dM -E - </dev/null | grep INTPTR
>>>> #define __INTPTR_MAX__ 2147483647
>>>> #define __INTPTR_TYPE__ int
>>>> #define __UINTPTR_MAX__ 4294967295U
>>>> #define __UINTPTR_TYPE__ unsigned int
>>>> $ i386-rtems4.11-gcc -dM -E - </dev/null | grep INTPTR
>>>> #define __INTPTR_MAX__ 2147483647L
>>>> #define __INTPTR_TYPE__ long int
>>>> #define __UINTPTR_MAX__ 4294967295UL
>>>> #define __UINTPTR_TYPE__ long unsigned int
>>>> I don't know whether to start sweeping through gcc and try to get
>>>> these all to just unsigned int or add target architecture specific logic
>>>> to fine tune the inttypes.h that newlib has. It looks like the
>>>> logic I added a few months cleared up a lot of these but not all.
>>> It's arguably a bug in gcc if the definitions don't match the base type.
>>> I think a patch to gcc would be preferable, but an additional workaround
>>> in newlib, if it's not too convoluted, wouldn't hurt, I guess.
>> Just to make sure we both are on the same page, you think that GCC
>> should define
>> it to "unsigned int", not "unsigned long int".
> Re-reading your mail I guess I misunderstood what you wrote.  I wrongly
> took it that when gcc uses int, it could use a long constant and vice
> versa.  But what you're saying is that the PRI{x}PTR macros are potentially
> wrong because newlib's inttypes.h doesn't take the type into account,
> only the size, right?
> I'm not so sure if the GCC guys take over responsibility for that, but
> it might be tricky to get this right.  AFAICS, glibc could also create
> error messages.  On 32 bit systems it never uses the 'l' length modifier
> for PRI{x}PTR macros, so it should 
> Maybe it *is* in order to fix that in GCC for the affected targets?!?
Now that I have looked a bit into the GCC side, I think it is kind of
newlib's fault. :)
newlib-stdint.h has this:

/* Newlib uses the unsigned type corresponding to ptrdiff_t for
   uintptr_t; this is the same as size_t for most newlib-using
   targets.  */

While glibc-stdint.h has this:

#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" :
"unsigned int")

I am pretty sure just using the glibc-stdint.h version would fix this
for most targets.

I am not sure about 16-bit targets or 32-bit address targets with 64-bit
longs if those exist.

What do you think?
> Corinna

Joel Sherrill, Ph.D.             Director of Research & Development        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985

More information about the Newlib mailing list