使用 callvirt 调用 base.ToString() 如何导致 StackOverflow 异常?
IL提供了两种调用函数的语句,即call和callvirt。 Call 用于调用非虚函数或静态函数或编译器不想对引用进行空检查的任何函数。
callvirt 用于调用虚函数,也调用非虚函数,因为编译器在运行时对引用进行空检查。
现在,在通过 C# 查看 CLR 时,我发现了以下示例。
internal class SomeClass
{
public override String ToString()
{
return base.ToString();
}
}
现在 ToString() 是虚函数,但是编译器为其生成调用指令是可以的。但是 Jeffrey 提到为什么不生成 callvirt 的原因是因为在这种情况下 ToString() 会被递归调用并会导致 StackOverFlow 异常,我试图理解但无法理解这个想法?谁能解释为什么它会导致递归调用?
谢谢..
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 while 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..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知,如果编译器生成 callvirt,就会发生 stackoverflow 异常,因为:
某些代码调用继承自类 object 的 someclass 类型的对象的 ToString。
*somclass 的 ToString 方法调用其基类(object)的 ToString 方法。
如果此调用将是虚拟的,则不会导致从以下位置调用 ToString类 object 但在实际类的 ToString 调用中(即 SomeClass),
那么你将处于不定式循环中,因为整个事情将从 new 开始。现在。
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.
对特定超类(在本例中为
System.Object
,因为您编写了base
)的显式调用不得为callvirt code> 因为这可能导致堆栈溢出。
一些 C# 伪代码:
希望这就是您的意思。
The explicit call to a specific super class (in this case
System.Object
because you wrotebase
) must not becallvirt
because that can lead to a stack overflow.Some C# pseudocode:
Hope that is what you meant.