Search code examples
.netvb.netexpression-trees

Compiler adding bitwise AND into expression tree with bit-shifting operation


I would expect the following code:

Dim i = 7, j = 5
Dim expr As Expression(Of Func(Of Integer)) = Function() i << j

to produce an expression tree of LambdaExpression with a single operation between the two variables i and j. Instead, the expression tree contains an additional bitwise & operation against 31, as can be seen in the following DebugView:

.Lambda #Lambda1<System.Func`1[System.Int32]>() {
    .Constant<_visualizerTests.VB.Module1+_Closure$__0-0>(_visualizerTests.VB.Module1+_Closure$__0-0).$VB$Local_i << (.Constant<_visualizerTests.VB.Module1+_Closure$__0-0>(_visualizerTests.VB.Module1+_Closure$__0-0).$VB$Local_j &
    31)
}

or, visually:

Expression Tree Visualizer screenshot

The same operation gets introduced when a right-shift is used.

The C# compiler doesn't seem to have the same behavior -- neither left-shift nor right-shift operators cause the compiler to introduce any additional operations.

Whey is this additional operation introduced?


Solution

  • From the docs:

    To prevent a shift by more bits than the result can hold, Visual Basic masks the value of amount with a size mask that corresponds to the data type of pattern. The binary AND of these values is used for the shift amount.