Immersing myself in the functional intricacies implied by the C# 3.0 extensions has led to a couple of interesting tests. Thought I'd share it for it's amusement value:
The first one comes from the wikipedia discussion of a "Sequence points":
[Test] public void ThisIsNotIntuitive() { int i = 0; i = i++; Assert.That(i, Is.EqualTo(0)); }This behavior is apparently undefined in C and C++ (It may be in C# too, dunno). The second one is taking this a step further and incorporates a closure to show how really evil doing this sort of thing is:
[Test] public void NeitherIsThis() { int i = 0; Predicate<int> f = (x) => x != i; Assert.That(f(i++), Is.True); }
Since there is a sequence point before function code is entered (again at least in C/C++) then at first glance, one might assume the test should assert IsFalse, but no - because i's value is placed into x then incremented, then the function body is entered so that by the time the evaluation occurs the numbers don't match.
This is visible in the disassembly of the expression call (I pulled it to a separate line). ebp-48h is "i" and ebp-4Ch is "x" (as an aside: notice how the value stuffed into "x" is retrieved and incremented and then mov'd to "i" rather than getting it from "i" in the first place. Works, but weird):
bool result = f(i++); 0000008d mov eax,dword ptr [ebp-48h] 00000090 mov eax,dword ptr [eax+4] 00000093 mov dword ptr [ebp-4Ch],eax 00000096 mov eax,dword ptr [ebp-4Ch] 00000099 inc eax 0000009a mov edx,dword ptr [ebp-48h] 0000009d mov dword ptr [edx+4],eax 000000a0 mov edx,dword ptr [ebp-4Ch] 000000a3 mov ecx,dword ptr [ebp-40h] 000000a6 mov eax,dword ptr [ecx+0Ch] 000000a9 mov ecx,dword ptr [ecx+4] 000000ac call eax
In addition to the two links above, this guy has more on this subject including (the hopefully unnecessary) "don't do this in your code."