VB.net Question

BloopBloop
Joined
Aug 9, 2012
Messages
891
Reaction score
275
Let me first post some code before asking the question.

VB Code:
Code:
Module Module1


    Sub Main()
        '
        Dim s As Byte = 100
        '
        Console.WriteLine(s << 8) '100 
        Console.ReadLine()
    End Sub


End Module

Other Language Codes:
C#
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            byte s = 100;
            Console.WriteLine(s << 8); // 25600
            Console.ReadLine();
        }
    }
}

Java
Code:
    public static void main(String[] args) {
        byte s = 100;
        System.out.println(s<<8);
    }



Code after decompiling the byte code.

C#
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(100 << 8); // 25600, treated as int
            Console.ReadLine();
        }
    }
}

Java
Code:
    public static void main(String[] args) {
        System.out.println(100<<8);
    }

VB Code in C# Context
Code:
internal sealed class Module1
  {
    [STAThread]
    public static void Main()
    {
      Console.WriteLine((int) (byte) (100U << 0));
      Console.ReadLine();
    }
  }





Now finally my question comes,

In all the cases, the code is treated as a integer, as far as i understand is this because the registers of the computer "prefer" to work with integers.

However, the VB.NET code actually gets "treated" as a byte,It is first casted to a byte, then the bit operation is applied (100 <<8 in a byte stays 100), then it is casted back to a integer

Why is this done? (in other words: Why does the VB.net byte "stays" as a byte and in Java,C# etc it doesn't)
 
Last edited:
See you take the value 100 (binary: 0110 0100 [64 + 32 + 4]) and shift it to left by 8 binary digits (binary: 0110 0100 0000 0000 [16384 + 8192 + 1024]).

# The rest of my statement was wrong, thanks Negata #
 
Last edited:
Well it took some time digging out the real cause for the problem because it was somewhat unexpected to me at least. Obviously there is something funny going on related to implicit type conversions. It turns out the left-shift << in C# (and apparently, in Java? - didn't check Java docs) only operates on ints, not bytes, while the VB version is fine with bytes as well. So in C# the byte is first implicitly cast into int and the shift is only then applied.

<< Operator (C# Reference)
"The left-shift operator (<<) shifts its first operand left by the number of bits specified by its second operand. The type of the second operand must be an int or a type that has a predefined implicit numeric conversion to int."
The wording here could be more explicit in stating what happens when a conversion is to be made, but it does hint towards the conversion happening before the shifting operation. Since there is the conversion to int and the variable is never used as a byte I suppose the compiler sees this and simply drops the byte declaration altogether int being the default numeric type.

As far as your question about registers goes, I don't think 8-bit registers really even exist anymore so in a way yeah they do prefer ints.

The result in C# is a bit funny (that it actually does a shift, but by 0 bits), however it's understandable given the VB docs. It states that the shifting value is masked to a value reasonable given the type of the first parameter - 8 masked with AND 7 will yield the 0 we see in the code in C# context. Then I suppose C# must make the conversion to byte in between just to make sure the resulting value is still in the 8-bit range and then convert it back to int again as there is no WriteLine version to operate on bytes like mentioned before.
 
Well it took some time digging out the real cause for the problem because it was somewhat unexpected to me at least. Obviously there is something funny going on related to implicit type conversions. It turns out the left-shift << in C# (and apparently, in Java? - didn't check Java docs) only operates on ints, not bytes, while the VB version is fine with bytes as well. So in C# the byte is first implicitly cast into int and the shift is only then applied.

Damn, I misread the given type of the variable.
Thanks for this explanation, I learned something new.
 
EDIT: Just rewording to make the essential clearer: the thing is, the << operator has different semantics in VB and C# and the results above are correct - they are expected to be different in this case. It's analogous to calling different functions although the symbol looks the same here.

Explanations on these things tend to get messy so easily so you can never word it in too many ways. :)
 
Last edited:
See you take the value 100 (binary: 0110 0100 [64 + 32 + 4]) and shift it to left by 8 binary digits (binary: 0110 0100 0000 0000 [16384 + 8192 + 1024]).

# The rest of my statement was wrong, thanks Negata #

The decompiler i used , for .NET, JettBrains and Java a online decompiler


Well it took some time digging out the real cause for the problem because it was somewhat unexpected to me at least. Obviously there is something funny going on related to implicit type conversions. It turns out the left-shift << in C# (and apparently, in Java? - didn't check Java docs) only operates on ints, not bytes, while the VB version is fine with bytes as well. So in C# the byte is first implicitly cast into int and the shift is only then applied.

<< Operator (C# Reference)
"The left-shift operator (<<) shifts its first operand left by the number of bits specified by its second operand. The type of the second operand must be an int or a type that has a predefined implicit numeric conversion to int."
The wording here could be more explicit in stating what happens when a conversion is to be made, but it does hint towards the conversion happening before the shifting operation. Since there is the conversion to int and the variable is never used as a byte I suppose the compiler sees this and simply drops the byte declaration altogether int being the default numeric type.

As far as your question about registers goes, I don't think 8-bit registers really even exist anymore so in a way yeah they do prefer ints.

The result in C# is a bit funny (that it actually does a shift, but by 0 bits), however it's understandable given the VB docs. It states that the shifting value is masked to a value reasonable given the type of the first parameter - 8 masked with AND 7 will yield the 0 we see in the code in C# context. Then I suppose C# must make the conversion to byte in between just to make sure the resulting value is still in the 8-bit range and then convert it back to int again as there is no WriteLine version to operate on bytes like mentioned before.

Thank you for the answer.
 
Back