什么都不返回或返回void - C#在void Function()调用结束时究竟做了什么?

时间:2013-08-15 19:18:23

标签: c# void void-pointers

考虑以下C#函数:

void DoWork()
{
    ...
}

C#文档声明:

  

当用作方法的返回类型时,void指定方法不返回值

这看起来很简单,在大多数情况下,这都是一个公平的定义。

然而,对于许多低级语言(即C),“void”具有略微不同的含义。具体来说,所有代码块都必须返回某些。因此,void是空指针的表示,它表示“无”。在这种情况下,您不需要在代码中包含return语句,因为任何不返回值的块语句都会自动返回空指针。

这是C#的作用或调用void函数时,它是否执行一段代码并返回,甚至没有包含值为void的指针?

3 个答案:

答案 0 :(得分:5)

首先,C#编译成IL,因此JIT后的最终表示可能不同。

使用void方法,IL中的方法签名将标记为voidret操作码仍然存在。这意味着,从IL的角度来看,调用堆栈上的“返回”值可能存在也可能不存在,但它永远不会被复制并在调用站点上使用。 ret操作码只会返回一个返回值(如果它存在),并且这不需要存在于void返回方法中,因此在很多情况下,它不会返回任何内容,即使是在低层次的概念立场。

  

然而,对于许多低级语言(即C),“void”具有略微不同的含义。具体来说,所有代码块都必须返回一些内容。

CLR不是这种情况。 void方法可以真正返回任何内容,因为ret操作码不允许返回任何内容。见OpCodes.Ret

  

从当前方法返回,将返回值(如果存在)从被调用者的评估堆栈推送到调用者的评估堆栈。

答案 1 :(得分:2)

如果this spec与官方语言规范类似,则未定义void方法/函数的返回值,这意味着,如果您想要一个空值,最好显式使用null而不是此。< / p>

在C中,使用void函数的返回值来获取null是一种不好的形式。 这是因为:

  1. 这会让下一个人感到困惑,
  2. 没有意义。如果您想要null,请使用null。如果希望void函数根据其计算返回值,请不要使用void返回类型和
  3. 最重要的是,由于它在技术上是不正确的,即使代码编译在当前版本的编译器上,它在将来的版本中可能根本不会编译,或者行为可能会意外地发生变化。
  4. 编辑:此外,如果单词assembly不会让你的脊椎冷得发抖......

    在C编译的底层x86汇编代码中,void函数确实无法返回任何内容。从函数返回值的想法实际上是由编译器实现的,所以如果你告诉编译器你不想要某个东西有一个返回值,那么就不会有一个。

    This documentret指令有一个很好的解释,以及它如何适合子程序调用约定(遗憾的是id元素在本文档中很少见,所以需要一点点滚动。但它就在那里。在页面上搜索ret

答案 2 :(得分:0)

在MSIL中,Ret可以选择返回一个值,因此void方法不会返回任何内容。 见http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ret.aspx

我不确定当MSIL被JIT编辑时如何处理。