Debugging often feels like a House episode
Did you ever feel like the Sherlock Holmes of coding when debugging by following the slightest clue that would lead to the root of the problem?
Bugs are either obvious or ridiculously hard to fix. To actually understand the nontrivial ones, often we need some out-of-the-box thinking.
Quite like an House episode. When the team seemingly hit a dead end trying to come up with a diagnostic, they start to reevaluate their hypothesis so far.
There’s this episode where House is delirious and so has to question which experiences are real. In order to do so, he start to question his team’s even most basic assumptions.
That’s kinda what we did when solving the following mysterious bug. Behold the code!
In this stripped down version of the offending code, we expected someField to end with the value of 11 after the IncrementSomeField() indirect call via the someAction delegate.
After some painful head scratching and double checking that the code flow was correct, we wondered what we were missing.
And then it came to us: what if the implicit this in IncrementSomeField() was not the same this for the myVar variable inside Test()? It’d explain it all. The someField indeed would be 11, but for another instance that was lost in the function call chain.
Now to the explaining! Turns out the this pointer is captured by value by the closure created at someAction += IncrementSomeField;. And since we’re using a struct and structs are value types, when we’re inside IncrementSomeField(), it’s actually a copy of our struct that we’re working with.
Because of that, our myVar variable is never touched and that’s why someField stays with its original value of 10.
That’s all folks! And keep on questioning your code reasonings!
This was your boy Matheus Lessa signing out and getting back to work. Peace!