This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [newlib] print formats for FAST and LEAST types


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]