How base.ToString() called using callvirt, can lead to a StackOverflow Exception?
IL offers two statements for calling functions, i.e. call and callvirt. Call is used to call the non-virtual or static functions or any function where compiler doesn't want to do a null check on the reference.
callvirt is used to call virtual functions, non-virtual functions are also called, since compiler does a null check on the reference at run time.
Now whil开发者_运维技巧e going through CLR via C# i found following example.
internal class SomeClass
{
public override String ToString()
{
return base.ToString();
}
}
Now ToString() is virtual function, but compiler generates the call instruction for it its ok.But the reason that Jeffrey mentioned that why callvirt is not generated because in that case the ToString() would be called recursively and will cause the StackOverFlow Exception, I tried to understand but was unable to wrap my mind around this idea ? Can anyone explain why it will cause a recursive call?
Thanks..
from what I believe, a stackoverflow exception would happen if the compiler generated callvirt because:
Some code calls ToString of an object of type someclass which inherits from the class object. The ToString of *somclass" method calls the ToString Method of it's base class which is object.
If this call would be virtual, it wouldn't result in call of ToString from the class object but in a call of ToString of the actuall class (which is SomeClass).
Then you whould be in an infinitive loop, as the whole thing would start from new now.
The explicit call to a specific super class (in this case System.Object
because you wrote base
) must not be callvirt
because that can lead to a stack overflow.
Some C# pseudocode:
internal class SomeClass
{
public override String ToString()
{
// The "return base.ToString()" call could produce one of these two possibilities:
// This will NOT go through the class hierarchy, searching for a overwritten function
// called ToString
call and return System.Object::ToString()
// But this WILL, thus calling SomeClass::ToString() recursively, so this is wrong
// and would lead to a stack overflow
callvirt and return System.Object::ToString()
}
}
Hope that is what you meant.
精彩评论