I have the following function:
public string MyPhrase(int val)
{
if ((val %3 == 0) && (val % 6 == 0))
return "Fizz Bang";
if (val % 3 == 0)
return "Fizz";
if (val % 6 == 0)
return "Bang";
return "";
}
After compiling this and viewing it with IlDasm, I get this output:
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: rem
IL_0003: brtrue.s IL_0010
IL_0005: ldarg.1
IL_0006: ldc.i4.6
IL_0007: rem
IL_0008: brtrue.s IL_0010
IL_000a: ldstr "Fizz Bang"
IL_000f: ret
IL_0010: ldarg.1
IL_0011: ldc.i4.3
IL_0012: rem
IL_0013: brtrue.s IL_001b
IL_0015: ldstr "Fizz"
IL_001a: ret
IL_001b: ldarg.1
IL_001c: ldc.i4.6
IL_001d: rem
IL_001e: brtrue.s IL_0026
IL_0020: ldstr "Bang"
IL_0025: ret
IL_0026: ldstr ""
IL_002b: ret
From looking at this page, brtrue will branch if true. What’s confusing me is the line IL_0003. Its saying that it should branch to line IL_0010 if its true. In my C# code though, I am using an && to compare two expressions before my program flow should jump to the next if. It seems backwards. From the MSIL code posted, it seems like its checking to see if my operation is true and if it is, its jumping to my next if block, which would be logically wrong. Can someone explain what I’m missing?
This is a side-effect of short circuit evaluation for the && operator. Which promises that the right-hand expression of the operator does not get evaluated if the left-hand side is false. So you see it skip the val % 6 == 0 expression and the return “Fizz Bang” statement if the REM opcode returns a non-zero result.