public class SelfCallingTest
{
private static int counter;
public void SelfCallingMethod(int counter)
{
Console.WriteLine("The input integer is: {0} ", counter);
counter++;
while (counter <= 2)
{
SelfCallingMethod(counter);
}
}
}
The above SelfCallingTest class has a static field name “counter” and the SelfCallingMethod takes an integer parameter named “counter” (same name as static instance member counter)
SelfCallingMethod is called from console test application Main() method
static void Main(string[] args)
{
SelfCallingTest sct = new SelfCallingTest();
sct.SelfCallingMethod(0);
Console.Read();
}
Now the problem is that while loop is going in infinite loop because when the value of counter method level variable reaches value = 3 then the thread control is coming out of the method and again resuming while loop execution with method level counter variable getting set to 2 – I am not sure why this counter is set to 2.
As soon as I change the method parameter name counter to other than static instance field name, the results are expected and console is printing 0, 1, 2
Could you please provide me an explanation? Is there a bug in the .NET CLR to read a value from TLS (thread local storage?)
I got what the problem is here, for the initiating callstack for the method SelfCallingMethod, while loop condition is always evaluating 2 ==2 and thats causing the infinite loop.
Your code is never using the static field. Look at this loop:
counteris a local variable (the parameter). It’s then passed by value toSelfCallingMethod, so that method call isn’t going to change it. How would you expect to ever exit the loop, other than via an exception?So what will happen is you’ll get a stack with
SelfCallingMethod(0), which callsSelfCallingMethod(1)(after the increment) which callsSelfCallingMethod(2)which callsSelfCallingMethod(3). That will increment its copy of the counter (to 4) and return… but then the loop fromSelfCallingMethod(2)will just go round and callSelfCallingMethod(3)again. Don’t forget that each call ofSelfCallingMethodhas a separatecountervariable.Yes, because at that point all the code using
counterin the method uses the field instead of the local variable. When the names are the same, the local variable hides the static variable. (You could still useSelfCallingTest.counterto access it explicitly though.)Absolutely not. The only bug is in your code, I’m afraid.