Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Mar 2000 03:04:46 -0500
From:      Garance A Drosihn <drosih@rpi.edu>
To:        hackers@FreeBSD.org
Cc:        Bruce Evans <bde@zeta.org.au>, Peter Dufault <dufault@hda.com>, Ed Hall <edhall@screech.weirdnoise.com>
Subject:   Re: Handling maximum values in C (was: MAX_UID)
Message-ID:  <v0421010db4ff669a1fd6@[128.113.24.47]>

next in thread | raw e-mail | index | archive | help
Recently on the freebsd-current mailing list, the topic came up of
setting the maximum value of a given type (uid_t, as the specific
example, but the conversation turned to having a generic way to
find the maximum value of any given type).  Some excerpts from
that thread:

> > > To get the all-1`s number, maybe it`s better to use ((uid_t)~0),
> > > but that is a rather controversial topic anyway.
> >
> > That works, but on machines like the Alpha where longs are bigger
> > than ints it only works by virtue of sign extension.  Our existing
> > headers seem to prefer ((uid_t)0-1).  That`s what is used in the
> > i386`s <machine/limits.h>.

> All 3 of these are broken in general.
> ((uquad_t)0-1) in <machine/limits.h> works because it is known that
> uquad_t is no smaller than int.  If foo_t is smaller than int, then
> (foo_t)0 in an expression gets promoted to plain 0, which is rarely
> what you want.
>
> ((uid_t)~(uid_t)0) is probably best.  The first cast gives a sufficient
> number of 0 bits and the second cast discards unwanted 1 bits.
>
> -1 is sometimes used instead of ~0 because there is a good rule
> for converting -1 to an unsigned type.  I can never quite remember
> this rule, so I prefer to use ~something.  Part of the rule is that
> (unsigned int)-1 has all bits 1 even if -1 doesn`t have all bits 1.

I've got some code I'm compiling on a number of different platforms
with a number of different compilers, and was running into a problem
depending on how 'char' (just plain 'char') was treated by default
(ie, signed vs unsigned).  Remembering the above, I thought "hey, I'll
just check the maximum value for type 'char'.  Once I found the messages,
it took me another 30 seconds to realize the above is only for
UNSIGNED types.  For signed types, all of the above just result in a
"max value" of -1...  (so imagine the fun if some arbitrary type is
changed from 'signed short' to 'unsigned int'...)

For those interested in using the above when they do know they have
an unsigned type, the:
    ((some_utype)~(some_utype)0)
version does seem to be the one which compiles without warnings
on the four compilers I tried (at least for unsigned char...).

The above was good enough to find out if plain 'char' is signed
or unsigned, but I'm wondering if there is any way to find the
max value of some_generic_integer_type, without assuming anything
about sizeof or signed/unsigned.  Some portable trick where the
value would be determined at compile-time, I mean...

Just wondering.

---
Garance Alistair Drosehn           =   gad@eclipse.acs.rpi.edu
Senior Systems Programmer          or  drosih@rpi.edu
Rensselaer Polytechnic Institute


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?v0421010db4ff669a1fd6>