~skeeto/public-inbox

1

1 << 31 is UB for signed int, but only in C

Details
Message ID
<dc2d96dd-59ca-431e-bec1-7c75a1ec36a2@waifu.club>
DKIM signature
pass
Download raw message
Hey Chris!

I have been trying to dip my toes into using signed types more and I
found something really annoying about left shifting in C:

https://godbolt.org/z/sMWj9s63Y

As you can see, what is essentially "1 << 31" is reported by UBSAN as an
error, but only in C, even when the standard is set to C23 and C++23, by
which point both languages adapted to reality where only 2's complement
integers exist.

Apparently, the C++ standard specifies that for bit-wise operators, the
operands are used as bags of bits, which results in the desirable behavior.

In C, you have to cast to the bit-width equivalent unsigned type and
then back to mimic the same behavior. I have not looked at what
standardese results in this difference, but the outcome is the same in
both GCC and Clang.

Just thought I'd let you know and I'm curious if you ever came across this.
Details
Message ID
<20240731225226.qc2chv6oqj4lmcg7@nullprogram.com>
In-Reply-To
<dc2d96dd-59ca-431e-bec1-7c75a1ec36a2@waifu.club> (view parent)
DKIM signature
missing
Download raw message
Yup, I've run into it frequently in the wild, usually on left shift by 24 
when assembling integers from bytes. For example, there's an instance in 
Rob Pike's otherwise excellent byte order fallacy article:

https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html

Cryptographic hash implementations often get it wrong, too. For example, 
here's a case in first result searching for "sha256.c":

https://github.com/B-Con/crypto-algorithms/blob/cfbde484/sha256.c#L49

It's not *really* about 2's complement, or lack thereof, but that C 
considers shifts arithmetic operators rather than bitwise as people 
usually think about them. From that point of view, 1<<31 cannot be 
represented, so it's an overflow. WG14 ought to follow C++ and remove the 
UB from C in this particular case. There should be less (but not zero) UB, 
and this is one that doesn't make sense.
Reply to thread Export thread (mbox)