Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between cast and strong type assignment?

I sort of ran into this today when writing some code. Take the following as an example:

long valueCast  = (long)(10 + intVariable);
long valueTyped = 10L + intVariable;

Is there any difference between these two or are they compiled to exactly the same thing? Is there a convention for one over the other?

So I know this isn't a critical question (both work). I'm just very curious about what the difference(s) might be!

EDIT - Modified the code example to be closer to what my original scenario actually is. I wanted the question to be clear so I replaced the variable with a constant. Didn't realize the compiler would to the arithmetic automatically (thereby changing the answers to this question)

like image 448
drew_w Avatar asked Mar 24 '14 14:03

drew_w


3 Answers

Yes, there's a big difference between those two. Not for those particular values, but the exact same expression with different values will show the difference.

In the first version, the addition is done in 32-bit arithmetic, and then the result is converted into a long.

In the second version, the first operand is already a long, so the second operand is promoted to long and the addition is then performed in 64-bit arithmetic.

Of course in this case the compiler will perform the arithmetic itself anyway (and come to the same conclusion in both cases), but it's important to understand the difference between converting the result of an operation, and converting one of the operands of an operation.

As an example:

unchecked
{
    long valueCast  = (long)(2000000000 + 2000000000);
    long valueTyped = 2000000000L + 2000000000;
    Console.WriteLine(valueCast);
    Console.WriteLine(valueTyped);
}

Result:

-294967296
4000000000

Note that this has to be done in an explicitly unchecked context, as otherwise the first addition wouldn't even compile - you'd get an error of "CS0220: The operation overflows at compile time in checked mode".

like image 176
Jon Skeet Avatar answered Sep 19 '22 06:09

Jon Skeet


Well, this is a compile error:

long valueCast = (long)(2147483647 + 2);

"The operation overflows at compile time in checked mode."

Whereas this works fine:

long valueTyped = (2147483647L + 2);

As Jon Skeet says, the difference is whether you convert to long before doing the sum, or afterwards.

like image 22
Tim Goodman Avatar answered Sep 19 '22 06:09

Tim Goodman


In your example , 10L + 2; equals ((long)10) + 2;

This is not the same as (long) (10+2) because:

(long)(10+2) operation executes as int (32bit) and then gets converted to long (64bit)

((long)10) + 2; operation executes as long (64bit) because 10 gets converted into long before the actual operation

like image 34
Sebastian Breit Avatar answered Sep 20 '22 06:09

Sebastian Breit