Subject: Re: off_t madness
To: None <tech-misc@NetBSD.org>
From: Alan Barrett <apb@cequrux.com>
List: tech-misc
Date: 02/05/2007 21:00:05
On Mon, 05 Feb 2007, Christian Biere wrote:
> #define MAX_INT_VAL_STEP(t) \
> 	((t) 1 << (CHAR_BIT * sizeof(t) - 1 - ((t) -1 < 1)))
> 	 
> #define MAX_INT_VAL(t) \
> 	((MAX_INT_VAL_STEP(t) - 1) + MAX_INT_VAL_STEP(t))
> 
> #define MIN_INT_VAL(t) \
> 	((t) -MAX_INT_VAL(t) - 1)

Without comments, it's too difficult to figure out what you are trying
to do here.

> 	 * Question: 
> 	 *
> 	 * Does the file fit into the buffer? (example: mmap())
> 	 *
> 	 * ret = filesize >= 0 && filesize <= bufsize;

> 	/* Option 1 */
> 
> 	ret = OFF_T_MAX > MY_SIZE_T_MAX
> 		? (filesize >= 0 && filesize <= (off_t)bufsize)
> 		: (filesize >= 0 && (my_size_t)filesize <= bufsize);
> 
> 	/*
> 	 * WRONG if OFF_T_MAX is wrong.
> 	 */

Ewww.  Even adding parentheses around the ?: term doesn't make this
less ugly.

> 	/* Option 2 */
> 
> 	ret = filesize >= 0
> 		&& (uintmax_t)(intmax_t)filesize <= (uintmax_t)bufsize;

This looks right (thought I would use parentheses around the && term).

> 
> 	/*
> 	 * WRONG if off_t is an extended integer type not covered by
> 	 * intmax_t. This is probably rather unlikely, so it might be
> 	 * the preferrable solution for ISO C99 code.
> 	 *
> 	 * example:
> 	 *
> 	 * typedef int64_t intmax_t;
> 	 * typedef __int128_t off_t;
> 	 */

That can't happen in C99.  intmax_t and unintmax_t are defined as the
longest integral types (section 1.18.1.5 of draft N1124 of the C99
standard).  There may be extended types longet than "long long" or
longer than int64_t, but not longer then intmax_t.  (In C89, "long" was
defined as the longest integral type, but common practice soon broke
that.)

--apb (Alan Barrett)