Hacker News new | ask | show | jobs
by EpicEng 4125 days ago
The first invokes UB if you assume that x is a local variable, and the second doesn't at all as far as I can tell. Care to explain?

To elaborate, the second expression has an underflow at 1 - sizeof(int) on an unsigned integer (promotion due to sizeof being unsigned), which is perfectly well defined:

"if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type."

The right shift is fine on a signed or unsigned integer. For the unsigned case (which is this one due to operator precedence), the behavior is well defined. For signed, implementation defined.

EDIT: The right shift is in fact UB assuming sizeof(int) <= 4.

1 comments

The behavior is only well defined if the shift amount is strictly less than the width of the operand. If `size_t` is 32 bits, then shifting right by 32 bits is undefined.

I know of three different ways in which platforms implement shifts by greater than the word size.

Yep, you're right. I knew left shift for signed/unsigned as it is more complicated and I've had to look it up more often, but I forgot that right shift can be UB for unsigned integral types as well.