is this a bug of JIT?

  • Thread starter Thread starter Justin Shen
  • Start date Start date
J

Justin Shen

the output of the following codes is "greater than zero", which is rather
strange! the correct one should be "not greater than zero"

int a = 0x79de61c0; //2044617152;
a += 0x12345678;
//a is 0x8c12b838 //-1944930248

if (a > 0)
{
Console.WriteLine("greater than zero");
}
else
{
Console.WriteLine("not greater than zero");
}

string str1 = a.ToString();


but if you comment out the "string str1 = a.ToString();",than the output is
correct:

int a = 0x79de61c0; //2044617152;
a += 0x12345678;
//a should be 0x8c12b838; //-1944930248

if (a > 0)
{
Console.WriteLine("greater than zero");
}
else
{
Console.WriteLine("not greater than zero"); //output is "not greater
than zero" now
}

anyone have any idea of this? The problem occurs in both VS2003 and VS2005 .
Is this a bug of JIT compiler?
 
Justin, FYI:
I had a Windows Application that I was working on open so I tried a different tack with the same results.

This works as advertised:

private void TestBug()
{
int a = 0x79de61c0; //2044617152;
a += 0x12345678; //a is 0x8c12b838 -1944930248
if(a>0)
System.Diagnostics.Debug.WriteLine("a>0 : " + a);
else
System.Diagnostics.Debug.WriteLine("a<0 : " + a);
}

Changing the a in either Debug line or both to:
a.ToString()
i.e.:
System.Diagnostics.Debug.WriteLine("a<0 : " + a.ToString());
causes the unexpected behaviour.


Haven't tried a Release build to see how that behaves.
--
....Carl Frisk
Anger is a brief madness.
- Horace, 20 B.C.
http://www.carlfrisk.com


Justin Shen said:
the output of the following codes is "greater than zero", which is rather
strange! the correct one should be "not greater than zero"

int a = 0x79de61c0; //2044617152;
a += 0x12345678;
//a is 0x8c12b838 //-1944930248

if (a > 0)
{
Console.WriteLine("greater than zero");
}
else
{
Console.WriteLine("not greater than zero");
}

string str1 = a.ToString();


but if you comment out the "string str1 = a.ToString();",than the output is
correct:

<*SNIP*>
 
Justin,
Does this work for you?

Setting it in a Try/Catch block caused the same? bug.

Coercing 'a' i.e. a=a; causes the correct, expected behavior in the example below and with a Try/Catch block.

private void TestBug()
{
int a = 0x79de61c0; //2044617152;
a += 0x12345678; //a is 0x8c12b838 -1944930248

a = a; //Workaround

if(a>0)
System.Diagnostics.Debug.WriteLine("a>0 : " + a);
else
System.Diagnostics.Debug.WriteLine("a<0 : " + a);
}
 
As it turns out the Release version fails with the other workaround. Not surprising.

private void TestBug()
{
int a = 0x79de61c0; //2044617152;
a += 0x12345678; //a is 0x8c12b838 -1944930248

int b=a; //Workaround
a=b; //Workaround

if(a>0)
// System.Diagnostics.Debug.WriteLine("a>0 : " + a.ToString());
Console.WriteLine("a>0 : " + a.ToString());
else
// System.Diagnostics.Debug.WriteLine("a<0 : " + a.ToString());
Console.WriteLine("a<0 : " + a.ToString());
}
 
Certainly looks like a bug. However, the post also has a misunderstanding
in it.

You state:
int a = 0x79de61c0; //2044617152;
a += 0x12345678;
//a is 0x8c12b838 //-1944930248

This is incorrect. The result is an integer overflow. The system will do
one of two things: if it is checked, it will throw an exception. If it is
unchecked, it will discard the MSB. Below is a direct quote from the c#
documentation:

<quote>
The arithmetic operators (+, -, *, /) can produce results that are outside
the range of possible values for the numeric type involved. You should refer
to the C# Language Reference section on a particular operator for details,
but in general:

Integer arithmetic overflow either throws an OverflowException or discards
the most significant bits of the result (see below). Integer division by
zero always throws a DivideByZeroException.
<clip>
When integer overflow occurs, what happens depends on the execution context,
which can be checked or unchecked. In a checked context, an
OverflowException is thrown. In an unchecked context, the most significant
bits of the result are discarded and execution continues. Thus, C# gives you
the choice of handling or ignoring overflow.
</quote>

So, while you do get some odd behavior, it is partly based on an odd
assumption on your part.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
Nick Malik said:
Certainly looks like a bug. However, the post also has a misunderstanding
in it.

You state:

This is incorrect. The result is an integer overflow. The system will do
one of two things: if it is checked, it will throw an exception. If it is
unchecked, it will discard the MSB.

The default context in C# is unchecked, in which case the above is
exactly correct. Try it:

using System;

class Test
{
static void Main(string[] args)
{
int a = 0x79de61c0;
a += 0x12345678;
Console.WriteLine (a);
}
}

The result is -1944930248, exactly as stated. The MSB is effectively
not discarded, but remains set and then interpreted as a sign bit.
 
Back
Top