Why isn't g++ tail call optimizing while gcc is?

前端 未结 3 1517
忘掉有多难
忘掉有多难 2020-12-31 15:36

I wanted to check whether g++ supports tail calling so I wrote this simple program to check it: http://ideone.com/hnXHv

using namespace std;

size_t st;

v         


        
3条回答
  •  北荒
    北荒 (楼主)
    2020-12-31 16:03

    I don't find the other answer satisfying because a local object has no effect on the stack once it's gone.

    Here is a good article which mentions that the lifetime of local objects extends into the tail-called function. Tail call optimization requires destroying locals before relinquishing control, GCC will not apply it unless it is sure that no local object will be accessed by the tail call.

    Lifetime analysis is hard though, and it looks like it's being done too conservatively. Setting a global pointer to reference a local disables TCO even if the local's lifetime (scope) ends before the tail call.

    {
        int x;
        static int * p;
        p = & x;
    } // x is dead here, but the enclosing function still has TCO disabled.
    

    This still doesn't seem to model what's happening, so I found another bug. Passing local to a parameter with a user-defined or non-trivial destructor also disables TCO. (Defining the destructor = delete allows TCO.)

    std::string has a nontrivial destructor, so that's causing the issue here.

    The workaround is to do these things in a nested function call, because lifetime analysis will then be able to tell that the object is dead by the tail call. But there's no need to forgo all C++ objects.

提交回复
热议问题