Return nothing or return void— What exactly does C# do at the end of a void Function() call?

微笑、不失礼 提交于 2019-12-04 04:21:07

问题


Consider the following C# function:

void DoWork()
{
    ...
}

The C# documentation states:

When used as the return type for a method, void specifies that the method does not return a value.

That seems straight-forward enough and, in most cases, that suits as a fair definition.

However, for many lower-level languages (i.e. C) "void" has a slightly different meaning. Specifically, all blocks of code must return something. Therefore, void is a representation of the null pointer which is a representation of "nothing". In such a case, you do not need to have a return statement within your code because any block-statement that doesn't return a value automatically returns a null pointer.

Is this what C# does or when a void function is called, does it execute a block of code and return without even having a pointer containing a value of void?


回答1:


First off, C# is compiled into IL, so the final representation post-JIT may differ.

With a void method, the method signature in IL will be marked as void, and the ret opcode will still exist. This means, from the standpoint of IL, the "returned" value on the call stack may or may not exist, but it will never get copied and used on the call site. The ret opcode will only push a return value if it exists, and this is not required to exist in a void returning method, so in many cases, it will not return anything, even in a low level conceptual standpoint.

However, for many lower-level languages (i.e. C) "void" has a slightly different meaning. Specifically, all blocks of code must return something.

This is not the case in the CLR. A void method can truly return nothing, as the ret opcode is allowed to not return anything. See OpCodes.Ret:

Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack.




回答2:


If this spec is anything like the official language specification, return value for void methods/functions is not defined, which means that, if you want a null value, it's best to explicitly use null rather than this.

In C, it is bad form to use the return value from a void function to get a null. This is because:

  1. It will be confusing to the next guy,
  2. It makes no sense. If you want null, use null. If you want the void function to return a value based on its computation, don't use a void return type, and
  3. Most importantly, since it is technically incorrect, even if the code compiles on the current version of your compiler, it may not compile at all in future versions, or the behavior may unexpectedly change.

edit: Additionally, if the word assembly doesn't send cold shivers up your spine...

In the underlying x86 assembly code that C compiles into, void functions really can return nothing. The idea of returning a value from a function is actually implemented by the compiler, so if you tell the compiler you don't want something to have a return value, there won't be one.

This document has a nice explanation of the ret instruction and how it fits into subroutine calling convention (unfortunately id elements are few and far between in this document, so it takes a bit of scrolling. But it's in there. Search for ret on the page).




回答3:


In MSIL, Ret can optionally return a value, so void methods doesn't return anything. See http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ret.aspx

I'm not sure how this is handled when MSIL is JIT-ed.



来源:https://stackoverflow.com/questions/18260043/return-nothing-or-return-void-what-exactly-does-c-sharp-do-at-the-end-of-a-voi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!