考虑以下C#函数:
void DoWork()
{
...
}
C#文档声明:
当用作方法的返回类型时,void指定方法不返回值。
这看起来很简单,在大多数情况下,这都是一个公平的定义。
然而,对于许多低级语言(即C),“void”具有略微不同的含义。具体来说,所有代码块都必须返回某些。因此,void
是空指针的表示,它表示“无”。在这种情况下,您不需要在代码中包含return
语句,因为任何不返回值的块语句都会自动返回空指针。
这是C#的作用或调用void
函数时,它是否执行一段代码并返回,甚至没有包含值为void的指针?
答案 0 :(得分:5)
首先,C#编译成IL,因此JIT后的最终表示可能不同。
使用void方法,IL中的方法签名将标记为void
,ret
操作码仍然存在。这意味着,从IL的角度来看,调用堆栈上的“返回”值可能存在也可能不存在,但它永远不会被复制并在调用站点上使用。 ret
操作码只会返回一个返回值(如果它存在),并且这不需要存在于void
返回方法中,因此在很多情况下,它不会返回任何内容,即使是在低层次的概念立场。
然而,对于许多低级语言(即C),“void”具有略微不同的含义。具体来说,所有代码块都必须返回一些内容。
CLR不是这种情况。 void方法可以真正返回任何内容,因为ret
操作码不允许返回任何内容。见OpCodes.Ret
:
从当前方法返回,将返回值(如果存在)从被调用者的评估堆栈推送到调用者的评估堆栈。
答案 1 :(得分:2)
如果this spec与官方语言规范类似,则未定义void方法/函数的返回值,这意味着,如果您想要一个空值,最好显式使用null而不是此。< / p>
在C中,使用void函数的返回值来获取null是一种不好的形式。 这是因为:
编辑:此外,如果单词assembly
不会让你的脊椎冷得发抖......
在C编译的底层x86汇编代码中,void函数确实无法返回任何内容。从函数返回值的想法实际上是由编译器实现的,所以如果你告诉编译器你不想要某个东西有一个返回值,那么就不会有一个。
This document对ret
指令有一个很好的解释,以及它如何适合子程序调用约定(遗憾的是id
元素在本文档中很少见,所以需要一点点滚动。但它就在那里。在页面上搜索ret
。
答案 2 :(得分:0)
在MSIL中,Ret可以选择返回一个值,因此void方法不会返回任何内容。 见http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ret.aspx
我不确定当MSIL被JIT编辑时如何处理。