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)