Removing undefined behavior of bitshifts

Timon Gehr timon.gehr at gmx.ch
Tue Jun 7 10:51:13 PDT 2011


Vladimir Panteleev wrote:

> On Tue, 07 Jun 2011 02:20:17 +0300, Timon Gehr <timon.gehr at gmx.ch> wrote:
>
>> I'd much prefer the behavior to be defined as 1<<x; being equivalent to
>> 1<<(0x1f&x); (That's what D effectively does during runtime. It is also
>> what the machine code supports, at least in x87).
>
> Can you think of any cases where this overflow behavior would be expected
> and useful? D can't (cheaply) catch runtime instance of this, but at
> compile-time it should definitely be an error.
>
> --
> Best regards,
>   Vladimir

My point is not that this behavior is expected and useful. It is what effectively
happens. And I agree that it might be a good idea to disallow it during compile
time. But the behavior during runtime should be _defined_! Saying "it's an error,
but it is not catched" is saying "the behavior is undefined." An optimizing
compiler could use this to ruin the memory safety of SafeD:

int[32] x;

@safe int foo(int shamt){
    int a=1<<shamt;
    x[shamt]++;
    return a;
}

What's the problem? Since the first line of foo is in error if shamt>31 or
shamt<0, the compiler can remove the bounds check on the array access. It cannot
screw anything up by doing that. If shamt is not in range, the whole program is
meaningless anyways. The compiler could as well make the program format your hard
drive whenever an illegal shift amount occurs. ;)

This is a hole in the language specification and needs to be fixed. It is not
about adding useful features that people want to use. It is about removing
undefined behavior while keeping the full performance. (of the shift operation)

BTW: Java handles it the same:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.19


Timon


More information about the Digitalmars-d mailing list