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: Add INTPTR_MIN, INTPTR_MAX, UINTPTR_MAX


Two things.
 
The first is related directly to the patch.  The problem is that when
__PTRDIFF_TYPE__ is defined, PTRDIFF_MAX and PTRDIFF_MIN are used but
they are not defined.  (They are defined in stddef.h, which is not even
in Newlib.)  I checked GCC3.4.4, and while __PTRDIFF_TYPE__ is a
predefined macro, the P...MIN&MAX are not.  A simple fix would be to
include <stddef.h>.  This, however, violates the standard, which says
that library include files are not to include other ones--but Newlib
already violates this, so perhaps it is not an issue.
 
Secondly, not directly related to the patch, I noticed that the related
part of stdint.h is not safe across all possible platforms.
 
The part of stdint.h under scrutiny is (not showing the patch
additions):
 
/*
 * GCC doesn't provide an appropriate macro for [u]intptr_t
 * For now, use __PTRDIFF_TYPE__
 */
#if defined(__PTRDIFF_TYPE__)
typedef signed __PTRDIFF_TYPE__ intptr_t;
typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
#else
/*
 * Fallback to hardcoded values,
 * should be valid on cpu's with 32bit int/32bit void*
 */
typedef signed long intptr_t;
typedef unsigned long uintptr_t;
#endif

The problem is as the comment in the else says, "SHOULD be valid ...
with ... 32 bit void *".  The statement is true, but the problem is that
not all platforms fall into that category--there is no guarantee that
a pointer fits in a long.  (On the other hand, are there any real
systems for which it presently does not?  This might only be a
theoretical problem rather than a real one at this time.)
 
The seemingly easy fix of getting rid of the else runs into a problem.
(The intptr_t and uintptr_t types are optional, except for POSIX
XSI-conformant systems, where they are required.)  And that is the use
of intptr_t and uintptr_t in 4+4 files (stdio's
vfprintf/vfscanf/vfwprintf/vfwscanf + 4 under sys/linux).  These places
could be re-done to use the kludge presently in stdint.h, but that would
be worse than the present state.
 
I can think of a few possible ways to fix it.

1)  Add machine/stdint.h (or some such) to set the size.
2)  Somehow get configure to figure it out.
3)  Blindly use long long when long long exists.
 
The recommended practice (in C99) is for ptrdiff_t is to be no larger
than long unless it has to be.  The same should probably apply to
intptr_t, which is one thing against #3.

Any other ideas?  (Maybe when this patch goes in, a FIXME note could be
added for until a proper fix can be done.)
 
Craig

-----Original Message-----
From: newlib-owner@sourceware.org [mailto:newlib-owner@sourceware.org]
On Behalf Of Hans-Peter Nilsson
Sent: Wednesday, April 08, 2009 4:03 PM
To: newlib@sourceware.org
Subject: [RFA:] stdint.h: Add INTPTR_MIN, INTPTR_MAX, UINTPTR_MAX

As required when the types are available.

...
 #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)
 #else
...

brgds, H-P


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