[ub] ub due to left operand of shift

John Regehr regehr at cs.utah.edu
Thu Oct 24 19:09:47 CEST 2013

Hi folks,

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 
application bugs.

- 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.


John Regehr

More information about the ub mailing list