This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [PATCH] newlib-stdint.h: Remove 32 bit longs
- From: Richard Earnshaw <Richard dot Earnshaw at foss dot arm dot com>
- To: Andy Ross <andrew dot j dot ross at intel dot com>, Joel Sherrill <joel dot sherrill at oarcorp dot com>, Andrew Pinski <pinskia at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, "<newlib at sourceware dot org>" <newlib at sourceware dot org>
- Date: Mon, 22 Aug 2016 19:35:21 +0100
- Subject: Re: [PATCH] newlib-stdint.h: Remove 32 bit longs
- Authentication-results: sourceware.org; auth=none
- References: <e7907443-eea0-87b5-87ba-fc34aa90c387@intel.com> <CA+=Sn1nAj0n2DJgwCUY434qxq-09zw62=+xt1JLbzS9dHo46jA@mail.gmail.com> <E14AB9B3-7DD2-47AF-A6E0-4A48EE7EC068@oarcorp.com> <17f8e287-d84c-ba2e-9a96-99c8eb22ab69@intel.com>
On 22/08/16 17:09, Andy Ross wrote:
> The reproduction is straightforward. Just build any cross gcc with
> --enable-newlib (e.g. the one in the Zephyr SDK) and compile this
> (on any 32 or 64 bit 2's complement architecture) with newlib's
> headers.
>
> #include <stdint.h>
>
> extern void takes_fmt(const char *fmt, ...)
> __attribute__ ((format (printf, 1, 2)));
>
> void foo()
> {
> int32_t x = 42;
> takes_fmt("%d", x);
> }
>
This code isn't portable. %d means that the argument is of type 'int'
but there is no requirement that int32_t is equivalent to 'int'.
If you have an int32_t then you should use PRIi32 or PRId32 as
appropriate. Of course, if the macros that those expand to still result
in warnings you probably have got a bug somewhere!
R.
> The use of int32_t with the untyped format specifier produces the
> "expects argument of type ‘int’, but argument 2 has type ‘long int’"
> warning despite the fact that this platform (it's just an i586
> compiler!) is a standard ILP32 architecture.
>
> The reason for that is this bit in newlib's headers where they trust
> gcc if __INT32_TYPE__ is set:
>
> https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/include/machine/_default_types.h;h=ffc646d9e3f5392a643f8b4ca203a3ad2a7627d8;hb=HEAD#l62
>
> And gcc, as seen by this patch, sets it to a long because it thinks
> that's what newlib *wants*.
>
> But if you look at the preprocessor code immediately following, newlib
> doesn't want that at all. If it doesn't find __INT32_TYPE__, it will
> (see line 70) clearly choose a signed int, not a long.
>
> Newlib doesn't want that at all. This just seems like some kind of
> historical mistake to me. GCC's newlib "support" causes newlib code
> to emit warnings on benign code that is unwarned in AFAIK literally
> every other platform in existence.
>
> (And I understand the point about the PRI stuff in inttypes.h, which
> we're doing internally. But that doesn't really address the bug in
> our SDK compiler.)
>
> Andy
>