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: [RFA:] stdint.h take 2: Add INTPTR_MIN, INTPTR_MAX, UINTPTR_MAX


Given that it is typical to use the lowest rank type that works, then
it would be possible to decide the right type, even if if both int and
long are the same size as pointers (e.g. 32 bits).  That is, if the
value
matches intmax, then it is int.  Otherwise it it long.  (This could
naturally be extended to include long long, of course.)
 
For example:

 #if defined(__PTRDIFF_TYPE__)
 typedef signed __PTRDIFF_TYPE__ intptr_t;
 typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
 #define INTPTR_MAX PTRDIFF_MAX
 #define INTPTR_MIN PTRDIFF_MIN
 #ifdef __UINTPTR_MAX__
 #define UINTPTR_MAX __UINTPTR_MAX__
 #else
+  #if PTRDIFF_MAX == __INT_MAX__
+    #define UINTPTR_MAX (2U * PTRDIFF_MAX + 1)
+  #else
+    #define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1)
+  #endif
-#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1)
 #endif
 #else
 
(Since it is already inside of #if defined(__PTRDIFF_TYPE__), it is a
given that __INT_MAX__ will exist.)
 
Thinking about this appears to have exposed another potential type
problem in stdint.h, in the value being used above:
/* This must match ptrdiff_t  in <stddef.h> (currently long int) */
#ifdef __PTRDIFF_MAX__
#define PTRDIFF_MAX __PTRDIFF_MAX__
#else
#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX)
#endif
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
 
The issue is that the type of PTRDIFF is assumed to be long, when it is
likely to really be int on many platforms.  (For example, GCC 3.4.4 and
4.3.2 on Cygwin both use __PTRDIFF_TYPE__ int, as would be expected for
ptr==int==long==32 bits.  In this case the value comes out right, but
the type is wrong.)
 
Note, too, that the comment is very misleading.  The 4.3.2 GCC stddef.h
does default to ptrdiff_t being long, but only if it has not been
defined otherwise.  Since the type is predefined by the compiler
(since 3.4.4, at least), assuming long is not very helpful, as that
assumption point is not hit.
 
I can think of no way to resolve the type problem for PTRDIFF_MAX,
other than putting it into config.h.  (Even GCC 4.3.2 does not have a
built-in preprocessor define that could be used.)
 
Thoughts?  (Patch attached in case there is agreement that this is
something that should be done.  Note that this also required a
rearrangement in the file because the PTRDIFF_MAX stuff is after the
UINTPTR stuff (which put some egg on my face a couple of weeks ago,
since I had failed to see it).  While doing the changes, I also put
in some indentation to make it easier to read.)
 
Craig
 
	* libc/include/stdint.h (UINTPTR_MAX):  Improve the way in
	which the type is assumed when the file assigns the value.


-----Original Message-----
From: newlib-owner@sourceware.org [mailto:newlib-owner@sourceware.org]
On Behalf Of Jeff Johnston
Sent: Friday, April 24, 2009 5:56 PM
To: Joseph S. Myers
Cc: Hans-Peter Nilsson; newlib@sourceware.org
Subject: Re: [RFA:] stdint.h take 2: Add INTPTR_MIN, INTPTR_MAX,
UINTPTR_MAX

Patch checked in.  Thanks.

-- Jeff J.

Joseph S. Myers wrote:
> On Thu, 9 Apr 2009, Hans-Peter Nilsson wrote:
>
>   
>>  #if defined(__PTRDIFF_TYPE__)
>>  typedef signed __PTRDIFF_TYPE__ intptr_t;
>>  typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
>> +#define INTPTR_MAX PTRDIFF_MAX
>> +#define INTPTR_MIN PTRDIFF_MIN
>> +#define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1)
>>     
>
> This UINTPTR_MAX definition is wrong (so causing gcc.dg/c99-stdint-1.c
to 
> fail) in the case where ptrdiff_t is int not long.  For long you want
the 
> 2UL, for int you want 2U.  There doesn't seem to be an obvious way to
get 
> the right choice; OK to commit this patch to use __UINTPTR_MAX__ for 
> compilers that define that (as is done with some other such macros
where 
> getting the right definition seems problematic without compiler
support)?
>
> 2009-04-24  Joseph Myers  <joseph@codesourcery.com>
>
> 	* libc/include/stdint.h (UINTPTR_MAX): Define to __UINTPTR_MAX__
> 	if __UINTPTR_MAX__ defined.
>
> Index: libc/include/stdint.h
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/include/stdint.h,v
> retrieving revision 1.14
> diff -u -r1.14 stdint.h
> --- libc/include/stdint.h	16 Apr 2009 18:29:51 -0000	1.14
> +++ libc/include/stdint.h	24 Apr 2009 13:20:37 -0000
> @@ -244,7 +244,11 @@
>  typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
>  #define INTPTR_MAX PTRDIFF_MAX
>  #define INTPTR_MIN PTRDIFF_MIN
> +#ifdef __UINTPTR_MAX__
> +#define UINTPTR_MAX __UINTPTR_MAX__
> +#else
>  #define UINTPTR_MAX (2UL * PTRDIFF_MAX + 1)
> +#endif
>  #else
>  /*
>   * Fallback to hardcoded values, 
>
>   

Attachment: stdint.h.patch
Description: stdint.h.patch


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