[ub] ub due to left operand of shift

Jens Maurer Jens.Maurer at gmx.net
Mon Oct 28 07:41:35 CET 2013


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


More information about the ub mailing list