Tags

, , , , , ,

After this post, someone contacted me personally and said he is very impressed with this article personally this is the first time someone call or email me for one of my blog post it sounds great right. Last friday, it started in a perfect manner. I got up and got a notification in Viber, same close person from out side Sri Lanka sent me this

AA Isham I want a simple question on the same topic (types and casting) to determine his C# knowledge.

I replied him

Ask for the difference between a = a + b; and a += b;

Funny question right, because all the books and our teachers taught both of them are same. When we were beginners we wrote some code, that returned same results and after we grow up a bit we checked IL code, yeah thats also same like the below,

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       12 (0xc)
  .maxstack  2
  .locals init ([0] int32 a,
           [1] int32 b)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  stloc.0
  IL_0004:  ldc.i4.s   10
  IL_0006:  stloc.1
  IL_0007:  ldloc.0
  IL_0008:  ldloc.1
  IL_0009:  add
  IL_000a:  stloc.0
  IL_000b:  ret
} // end of method Program::Main

for both of the below,

static void Main(string[] args)
{
    int a = 10;
    int b = 10;
    a = a + b;
}

and

static void Main(string[] args)
{
    int a = 10;
    int b = 10;
    a += b;
}

so what the difference could be, and this seems a foolish question and answer should be “No differences” right? but you are wrong.

293906a

You want proof, okay open Visual Studio, make it two (shift + click on the VS icon on taskbar) make two console applications and write below on each of them

static void Main(string[] args)
{
    short a = 10;
    short b = 10;
    a = a + b;
}
static void Main(string[] args)
{
    short a = 10;
    short b = 10;
    a += b;
}

VS will tell the first one is buggy. Leave it and run the second one, it will run without any errors.

short + short = int

Because this is how C# designers see it. In C# size order for Integral types comes like byte < char < short < int < long and practically type int can cover “most” calculations. Programmers rarely use short or byte when it comes to complex arithmetic. I mean we don’t “practically see 10 short values are added and multiplied and divided and again assigned to short you know. You might argue, but its the “practical” truth and add CIL instruction is optimized towards int. 16 bit arithmetic are too slow. And yeah, arithmetic operations in short are 16 bit ones. If you are interested on why this is slow, read this.

But still they gave option, that runs a += b because there should be an option for adding at-least two short or lesser types and add push it to a short type variable right. So to cover this what they have done is, they added an additional conv.i2 statement which does the job of casting the operation to Int16. For the last code piece above I got the IL code like below

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       13 (0xd)
  .maxstack  2
  .locals init ([0] int16 a,
           [1] int16 b)
  IL_0000:  nop
  IL_0001:  ldc.i4.s   10
  IL_0003:  stloc.0
  IL_0004:  ldc.i4.s   10
  IL_0006:  stloc.1
  IL_0007:  ldloc.0
  IL_0008:  ldloc.1
  IL_0009:  add
  IL_000a:  conv.i2
  IL_000b:  stloc.0
  IL_000c:  ret
} // end of method Program::Main

So, its something like, a += b means a = (short)(a + b);. Which makes your code size bit more than if you have used int. Look at the above IL code also there, the code size is 13 but for the same code size if I have used int it is 12 (look at the first IL code).

So in best practice, do think too small means too optimal really it will cost some other way you don’t know. Read C# specifications well. I mainly want this to who write code in Xamarin free subscription because they have an IL code limitation.

Advertisements