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

后端 未结 3 1056
醉梦人生
醉梦人生 2021-01-20 17:34

Consider the following C# function:

void DoWork()
{
    ...
}

The C# documentation states:

When used as the return t

相关标签:
3条回答
  • 2021-01-20 17:38

    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).

    0 讨论(0)
  • 2021-01-20 17:39

    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.

    0 讨论(0)
  • 2021-01-20 17:49

    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.

    0 讨论(0)
提交回复
热议问题