[ub] ub due to left operand of shift
regehr at cs.utah.edu
Thu Oct 24 19:09:47 CEST 2013
I wanted to take the recent discussion of integer undefined behaviors in
a slightly different direction, and bring up some issues with the left
operand of the signed left-shift operator.
The C99 standard, and also the latest working drafts of C11 and C++11
that I know of, effectively forbid shifting a 1 bit into, out of, or
through the sign bit. But also we have this, which proposes
strengthening the behavior the allow shifting into the sign bit but not
out of it or past it:
Here are a few observations about this class of undefined behavior:
- As one of the people who helped get good integer undefined behavior
checking into Clang 3.3, I ran a large amount of open source software
with these checks turned on. Basically every large open source program
is undefined due to the LHS rules for signed left shift.
- These undefined behaviors are extremely surprising to developers.
Moreover, developers do not care about them. In fact, we stopped
reporting them as bugs because this was hurting our credibility as
providers of useful, previously-unknown information about potential
- Every C compiler that I have used provides the semantics that
developers expect: signed left-shift works the same as unsigned left
shift. I wrote a number of undefined test cases where the compiler could
generate better code due to the ub and no compiler did this. This was a
while ago but I recall trying Intel CC, GCC, and LLVM.
- Non-two's complement platforms are all but nonexistent.
Given all of the above, I would propose strengthening the semantics of
signed left shift even farther than Howard Hinnant, and simply
eliminating these highly surprising undefined behaviors and instead
specifying that the result of a signed left-shift is the same as would
be obtained using the equivalent unsigned type.
More information about the ub