[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Having fun with the following C code (UB)



On 2014-04-10 12:42:03 +0200, Wouter Verhelst wrote:
> On Thu, Apr 10, 2014 at 12:29:50PM +0200, Jakub Wilk wrote:
> > * Wouter Verhelst <wouter@debian.org>, 2014-04-10, 12:03:
> > > I've had to figure out the size of off_t in nbd-server, and have
> > > been doing it without relying on overflow, for years now. It took
> > > quite a few iterations to get it right, but the current definition
> > > has looked like this since 2006:
> > >
> > > #define OFFT_MAX ~((off_t)1<<(sizeof(off_t)*8-1))
> > >
> > > i.e., left-shift 1 by enough bits so that the most significant bit
> > > is set,
> >
> > I believe that this code triggers undefined behavior. My C99 draft
> > reads:
> >
> > The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
> > bits are filled with zeros. […] If E1 has a signed type and
> > nonnegative value, and E1 × 2^(E2) is representable in the result
> > type, then that is the resulting value; otherwise, the behavior is
> > undefined.
>
> Yes; the standard does this to allow for machine architectures which
> do not use two's complement to store negative values. I did mention
> that assumption in my previous mail.
>
> If the architecture uses two's complement, however, then the code is
> correct.

Chapter and verse?  C99, sec. 6.5.7, para. 4, quoted above, makes no
such distinction.  The operation is simply defined in terms of multi-
plication by powers of two.  If off_t is a signed type,

  1 * 2 ^ (sizeof (off_t) * CHAR_BIT - 1)

cannot be represented in off_t, and the behaviour is undefined.

Az.

Attachment: signature.asc
Description: Digital signature


Reply to: