C++ Logo

sg12

Advanced search

Re: [ub] ub due to left operand of shift

From: Lawrence Crowl <Lawrence_at_[hidden]>
Date: Wed, 30 Oct 2013 17:46:31 -0700
On 10/27/13, Jens Maurer <Jens.Maurer_at_[hidden]> wrote:
> On 10/28/2013 05:31 AM, Lawrence Crowl wrote:
> > The original definition fails for the earlier example.
> >
> > int adjust( unsigned char E1 ) { return E1 << 24; }
> >
> > E1 is unsigned, and therefore the text says to compute mod
> > INT_MAX rather than UINT_MAX. This behavior is clearly not
> > what anyone is doing.
>
> Here's 5.8p2. E1 and E2 are assumed to have their promotions
> already applied. (I believe this is standard phrasing, but
> could be made clearer.)

Can read the text another way, though your reading matches the
existing behavior.

> The value of E1 << E2 is E1 left-shifted E2 bit positions;
> vacated bits are zero-filled. If E1 has an unsigned type, the
> value of the result is E1 × 2^E2, reduced modulo one more than
> the maximum value representable in the result type. Otherwise,
> if E1 has a signed type and non-negative value, and E1 × 2^E2
> is representable in the corresponding unsigned type of the
> result type, then that value, converted to the result type, is
> the resulting value; otherwise, the behavior is undefined.
>
> Why does your example from above fail?

It doesn't under your reading.

However, I have another issue.

#include <iostream>
void print_type( int arg )
  { std::cout << "unsigned" << std::endl; }
void print_type( unsigned int arg )
  { std::cout << "signed" << std::endl; }
int main()
  { print_type( 3 << 2u ); }

will print "unsigned". It seems really odd to me to have
the shift count poison the sign of the value when the count
sign is not relevant to the computation. Again, probably not
something we can change.

-- 
Lawrence Crowl

Received on 2013-10-31 01:46:33