From owner-freebsd-hackers Thu Mar 23 0: 4:21 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from mail.rpi.edu (mail.rpi.edu [128.113.100.7]) by hub.freebsd.org (Postfix) with ESMTP id 7F2BE37BDE4 for ; Thu, 23 Mar 2000 00:04:12 -0800 (PST) (envelope-from drosih@rpi.edu) Received: from [128.113.24.47] (gilead.acs.rpi.edu [128.113.24.47]) by mail.rpi.edu (8.9.3/8.9.3) with ESMTP id DAA48080; Thu, 23 Mar 2000 03:04:04 -0500 Mime-Version: 1.0 X-Sender: drosih@mail.rpi.edu Message-Id: Date: Thu, 23 Mar 2000 03:04:46 -0500 To: hackers@FreeBSD.org From: Garance A Drosihn Subject: Re: Handling maximum values in C (was: MAX_UID) Cc: Bruce Evans , Peter Dufault , Ed Hall Content-Type: text/plain; charset="us-ascii" ; format="flowed" Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 . > All 3 of these are broken in general. > ((uquad_t)0-1) in 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