Calling a non-void function without using its return value. What actually happens?

给你一囗甜甜゛ 提交于 2019-12-14 04:16:40

问题


So, I found a similar question here, but the answers are more about style and whether or not you are able to do it.

My question is, what actually happens when you call a non-void function that returns an object, but you never assign or use said returned object? So, less about whether or not you can, because I absolutely know you can and understand the other question linked above... what does the compiler/runtime environment do?

This is not a language specific question, but if you answer, please specify what language you are referring to, since behaviors will differ.


回答1:


I believe that for both C# and Java, the result ends up on the stack, and the compiler then forces a pop instruction to ignore it. Eric Lippert's blog post on "The void is invariant" has some more information on this.

For example, consider the following C# code:

using System;

public class Test 
{
    static int Foo() { return 10; }

    public static void Main()
    {
        Foo();
        Foo();
    }
}

The IL generated (by the MS C# 4 compiler) for the Main method is:

.method public hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: call int32 Test::Foo()
    L_0005: pop 
    L_0006: call int32 Test::Foo()
    L_000b: pop 
    L_000c: ret 
}

Note the calls to pop - which disappear if you make Foo a void method.




回答2:


what does the compiler do?

The compiler generates a pop instruction that discards the result off the virtual stack.

what does the runtime environment do?

It typically jits the code into code that passes the return value back in a register, rather than a stack location. (Typically EAX on x86 architectures.)

The jitter knows that the value will go unused, so it probably generates code that clears the register. Or perhaps it just leaves it hanging around in the register for a while.

Which runtime environment do you care about? There are lots of them, and they all have different jitters.




回答3:


It depends a bit on the calling convention being used. For small/simple types, the return will typically happen in a register. In this case, the function will write the value into the register, but nothing else will pay attention, and the next time that register is needed (which will typically happen pretty quickly) it'll be overwritten with something else.

For larger types, the compiler will normally allocate a structure to hold the return value. Exactly where/how it does that allocation will vary with the compiler though -- in some cases it'll be a static structure, and the contents will be ignored and overwritten the next time you call a function returning the same type. In other cases it'll be on the stack, and even though you haven't used it, it still needs to be allocated before the function is called, and freed afterwards




回答4:


For C++, typically, the compiler will optimize out the returning of the variable, turning it into a void function, and if this enables further optimizations, the compiler may optimize out the entire function call or parts of it that only pertain to the return value. For Java and C#, I have little idea.




回答5:


In .NET, if the object being returned is a reference type, and the application has no other references to that object, then you'll still have an object floating around in memory until the garbage collector decides to collect it.

This is potentially bad if the object being returned happens to be holding on to resources. If it implements the IDisposable interface, then your code ought to be calling the Dispose method on it, but in this case the Dispose method would never be called.

EDIT: corrected a typo.



来源:https://stackoverflow.com/questions/3998368/calling-a-non-void-function-without-using-its-return-value-what-actually-happen

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