【问题标题】:Return nothing or return void-- What exactly does C# do at the end of a void Function() call?不返回任何内容或返回 void——C# 在 void Function() 调用结束时究竟做了什么?
【发布时间】:2013-08-18 01:50:27
【问题描述】:

考虑以下 C# 函数:

void DoWork()
{
    ...
}

C# 文档指出:

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

这似乎很简单,并且在大多数情况下,这适合作为一个公平的定义。

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

这是 C# 所做的,还是在调用 void 函数时,它是否会执行一段代码并在没有包含 void 值的指针的情况下返回?

【问题讨论】:

    标签: c# void void-pointers


    【解决方案1】:

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

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

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

    在 CLR 中情况并非如此。 void 方法可以真正返回任何内容,因为 ret 操作码允许不返回任何内容。见OpCodes.Ret

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

    【讨论】:

    【解决方案2】:

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

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

    1. 这会让下一个人感到困惑,
    2. 这毫无意义。如果你想要 null,请使用 null。如果您希望 void 函数根据其计算返回一个值,请不要使用 void 返回类型,并且
    3. 最重要的是,由于它在技术上是不正确的,即使代码在当前版本的编译器上编译,也可能在未来的版本中根本无法编译,或者行为可能会意外改变。

    编辑:此外,如果 assembly 这个词没有让你脊背发凉......

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

    This document 很好地解释了ret 指令以及它如何适应子例程调用约定(不幸的是,id 元素在本文档中很少而且相距甚远,因此需要一些滚动。但它在那里。在页面上搜索ret)。

    【讨论】:

      【解决方案3】:

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

      我不确定当 MSIL 采用 JIT 时如何处理。

      【讨论】:

      • 这越来越接近我感兴趣的细节水平了。
      猜你喜欢
      • 2021-12-22
      • 2016-04-21
      • 2011-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-08
      相关资源
      最近更新 更多