C++ Logo

sg12

Advanced search

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

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Mon, 28 Oct 2013 07:41:35 +0100
On 10/28/2013 04:24 AM, Lawrence Crowl wrote:
> Sigh, I think promoting unsigned to signed is broken, but I do
> not think we can change it. Does any compiler have a warning
> for this behavior?

Sure, gcc does:

int main(int argc, char **argv)
{
  unsigned int x = (unsigned char)argc << 7;
}

> g++ -Wsign-conversion shift.cc
shift.cc: In function ‘int main(int, char**)’:
shift.cc:3:43: warning: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Wsign-conversion]

>>> However, I think p2 saves our intrepid developer in C++14:
>>> "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;"
>>
>> We gave this defined behavior as a DR, so I view this code has
>> having de facto defined behavior in C++11 and C++98 too. But
>> it's UB in C.
>
> Can you point to the DR? I cannot find it.

Core issue 1457.

>> In other words, we've already fixed this one (for some value
>> of "fixed").
>
> Right, we defined it to be what people were getting already.
> While I think that was the only really practical choice, I would
> rather see a less permissive option available to programmers
> that do not want to stray from "mathematically expected" results.

You can always define your own "lshift" function with the appropriate
asserts, right?

Jens

Received on 2013-10-28 07:41:52