The call stack does not say “where you came from”, but “where you are going next”?

后端 未结 5 1180
南旧
南旧 2020-11-30 03:51

In a previous question (Get object call hierarchy), I got this interesting answer:

The call stack is not there to tell you where you came from.

5条回答
  •  暖寄归人
    2020-11-30 03:54

    Consider the following code:

    void Main()
    {
        // do something
        A();
        // do something else
    }
    
    void A()
    {
        // do some processing
        B();
    }
    
    void B()
    {
    }
    

    Here, the last thing the function A is doing is calling B. A immediately returns after that. A clever optimizer might optimize out the call to B, and replace it with just a jump to B's start address. (Not sure whether current C# compilers do such optimizations, but almost all C++ compilers do). Why would this work? Because there's an address of the A's caller in the stack, so when B finishes, it would return not to A, but directly to A's caller.

    So, you can see that the stack does not necessary contain the information about where did the execution come from, but rather where it should go to.

    Without optimization, inside B the call stack is (I omit the local variables and other stuff for clarity):

    ----------------------------------------
    |address of the code calling A         |
    ----------------------------------------
    |address of the return instruction in A|
    ----------------------------------------
    

    So the return from B returns to A and immediately quits `A.

    With the optimization, the call stack is just

    ----------------------------------------
    |address of the code calling A         |
    ----------------------------------------
    

    So B returns directly to Main.

    In his answer, Eric mentions another (more complicated) cases where the stack information doesn't contain the real caller.

提交回复
热议问题