I've been looking at some old, (Reflector) decompiled source code that I dug up. The DLL was originally compiled from Visual Basic .NET source, using .NET 2.0 - apart from that I have no information about the compiler anymore.
At some point something strange happened. There was a branch in the code that wasn't followed, even though the condition should have holded. To be exact, this was the branch:
[...]
if (item.Found > 0)
{
[...]
Now, the interesting part was that if item.Found was -1
, the scope of the if
statement was entered. The type of item.Found
was int
.
To figure out what was going on, I went looking in the IL code and found this:
ldloc.3
ldfld int32 Info::Found
ldc.i4.0
cgt.un
stloc.s flag3
ldloc.s flag3
brfalse.s L_0024
Obviously Reflector was wrong here. The correct decompiled code should have been:
if ((uint)item.Found > (uint)0)
{ ... }
OK so far for context. Now for my question.
First off, I cannot imagine someone actually writing this code; IMO no-one with a sane mind makes the distinction between '-1' and '0' this way - which are the only two values that 'Found' can have.
So, that leaves me with the conclusion that the compiler does something I do not understand.
- Why on earth / in what context would a compiler generate IL code like this? What's the benefit of this check (instead of
ceq
orbne_un
- which is what I would have expected and is normally generated by C#)? - And related: what was the original source code most likely?
As an experiment I compiled this VB code:
The IL for the release version of this is:
Note the use of
cgt.un
Reflector's interpretation as C# is:
And as VB:
Therefore I conclude the generated code is related to the conversion of the VB Boolean to a numeric value.