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]

stdint.h INT_LEAST defines


I was just examining stdint.h (from newlib 1.16.0), and think that the
definition methods for the INT_LEAST... sets are probably not quite
correct for all situations.
 
For example, consider the type int_least8_t (lines 266-272):
#if __int_least8_t_defined
#define INT_LEAST8_MIN  -128
#define INT_LEAST8_MAX   127
#define UINT_LEAST8_MAX  255
#else
#error required type int_least8_t missing
#endif
 
The minimum is hard-coded to be -128.  However, this is not necessarily
true.  Earlier in the file (lines 75-79, not all context preserved):
#if !__int_least8_t_defined
typedef int16_t         int_least8_t;
typedef uint16_t        uint_least8_t;
#define __int_least8_t_defined 1
#endif
 
This means that int_least8_t can be 16 bits (when an 8-bit type is not
available), in which case INT_LEAST8_MIN ought to be -32768.  That is, I
believe that the define is supposed to be what the type actually can
hold,
not the minimum that it is required to hold.  While the standard
requires
that INTn_MIN be exactly -(2^(n-1)), it requires that INT_LEASTn_MIN be
<=
-(2^(n-1) - 1).  (e.g. INT_LEAST8_MIN must be <= -127).  It would have
been
nice if they were explicit that the INT_LEASTn macros should be the
actual
minima and maxima, but although they were not, it is definitely implied
by
the defined ranges for them when compared to the exact numbers for the
fixed-width types.  (This principle is already demonstrated in stdint.h
by
INT_LEAST8_MIN=-128, which is one less than the required -127,
reflecting
that twos-complement 8 bits does more.  However, this might also be
construed
as an error in the standard, where they have accidently included the
latter
-1 in the equation, where the same odd seemingly-extra -1 appears in
both
INT_LEASTn_MIN and INT_FASTn_MIN.)
 
So in implementations where the int_least sizes actually get the
matching
size (but not bigger), the INT_LEAST... defines are correct.  But if the
supplied type is larger than the least required, they will be wrong.
 
So the basic question that this email is raising is:  are the INT_LEAST
set of defines supposed to reflect the actual range that the respective
int_least types can hold, or should they only reflect the range that
they
are required to hold?  I propose that the former is the case.  It is
strongly implied by the language in the standard, as mentioned in the
previous paragraph.
  
If my assertion is true, then stdint.h would need to be edited to
something
more like (combining the two previous snippets with value edits):
#if !__int_least8_t_defined
typedef int16_t         int_least8_t;
typedef uint16_t        uint_least8_t;
# define INT_LEAST8_MIN  -32768
# define INT_LEAST8_MAX   32767
# define UINT_LEAST8_MAX  65535
# define __int_least8_t_defined 1
#endif
/* (Using INT16_MIN, etc., would be better in terms of demonstrating the
"inheritance", but I used hard numbers for the purposes of this email.)
*/
 
If there is an agreement about my conclusions, I could possibly supply a
new
version of stdint.h with the needed changes.  It would be interesting
for the
listed author, Ralf Corsepius, to weigh in on this, as he took the time
to
compose it to begin with, and made the decision to fix the limits
independently of the actual size.  (stdint.h seems to have been
introduced in
1.14.0, and has remained unchanged with respect to the INT_LEAST...
defines
through 1.16.0.)  A brief perusal of web results shows that most places
seem to have hard-coded the limits independently of the actual size, but
it
also appears that most of them are from newlib.
 
Craig Howland


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