I work in C# usually writing support programs for embedded projects. I inherited a project from someone long gone, which is a program used by one of my customers to download and upload Intel Hex files via RS-232 to some of their boards. The program worked fine for them for a number of years, but with the new board which I am working on it did not, and needed some modifications.
I opened the project, and found the issue. The new board was producing some data at addresses in the range 0x90000000-0x9007FFFF
, and the C# code was using the int
type for the address data; which is signed, which incorrectly handled addresses over 0x80000000
. So far, so good. But then I got cocky.
I decided to clean up the code, replacing all "int" with Int16/UInt16/Int32/UInt32, depending on the usage. It took a while, but I figured it would make the code clearer and more understandable, and hopefully avoid any future bugs.
The code ceased to work. It took me most of the day, and it boiled down to this line:
currseg = (HexSegment)hex_segments[HashEntry];
The type HexSegment is a struct (yes, struct, not a class),
public struct HexSegment
{
UInt32 Address; // this is the fix I made, both were int
UInt32 Buf_idx;
}
hex_segments is a HashTable.
finally, HashEntry was an "int", also made into an UInt32
.
In the debugger I see this:
If you can't see the image, the value of HashEntry is 0x00000000
.
If I ask the debugger to see hex_segments[0]
, I get a MLV.HexSegment
with legitimate data.
If I ask the debugger to see hex_segments[HashEntry]
, I get null!!
Changing HashEntry
to Int32
fixed the issue.
Like I said, I'm an embedded programmer. To me, this is a big mystery. Is there anybody who can explain why this is like this?
Because Hashtable is indexed by object not by int.
public virtual object this[object key] { get; set; }
so if an object was added with key 0 as Int32, it would be different than an object added with 0 as UInt32.
Have a look at this:
UInt32 index = 0;
Int32 index2 = 0;
Hashtable t = new Hashtable();
t.Add(index, new { name = "matt" });
t.Add(index2, new { name = "Matt" });
var obj = t[index];
var obj2 = t[index2];
Console.WriteLine(obj);
Console.WriteLine(obj2);