Where is the function that a decayed lambda to pointer points to stored? How is it released?

Asked

Viewed 74 times

3

I learned recently that I can do this:

auto a = +[]{return true;};
a = +[]{return false;};

And I understood that a lambda that captures nothing can decay to a pointer for function, as confirmed by GCC:

bool (*)()

But where is the actual object the lambda points to stored? How is it released? Why can I store a pointer for a temporary lambda object? I understand that there is an exotic case in language in which a constant reference can extend the life of an object, so I expected the lambda conversion to return something like this, not a pure pointer.

  • 1

    It seems to me that in automatic storage ("stack"), and that it does not necessarily decay, but rather can be converted into pointer to function, but whether or not it can be used in C-style calls is dependent on implementation. Stay tuned, because the behavior observed in an implementation is not necessarily the way it will always be.

  • Thanks. I’m researching the answers and it seems that Amblas has some freedom of implementation... If this proves true, I will ask you to elaborate the comment in response.

2 answers

4

According to some answers in a question in the OS a structure is generated with the captured data and an access form. Then an instance is generated for the lambda where the data is stored. Another interesting question with similar content.

Destruction will occur when the variable is out of scope (it may have an extended lifespan depending on how it is used).

In thesis you can put a pointer to this object, I just don’t know if it’s a good idea (of course it depends on what you’re going to do with it).

There’s a another interesting question in the OS linked by Pablo Almeida in comment.

  • Thanks. I posted the question there too and the answers (of the linked questions) seem contradictory, I will search a little more.

  • As your answer refers to state (which capture variables) and these cannot be converted to pointers-for-function, my question does not apply. And because Pablo Almeida’s comment cites implementation freedoms that, I realized, do not extend to the point of affecting that guarantee, I drafted my own response. I hope it’s not too inelegant.

  • 1

    It’s good, it always helps more people.

0


(gathering information from related questions suggested with the answer to replica of the question on the website in English, I came to the following conclusion:)

When declaring a lambda, the compiler generates the equivalent of a new type, with an undefined and unique name, which has a operador() containing the body of the defining function.

If a lambda does not capture variables, C++ allows it to decay to an ordinary pointer for this function (and this conversion is invoked when applying the operador+, returning your address).

As functions are stored in a separate area of memory - all functions in C++ are - the pointer remains valid throughout the execution of the program, and the destruction of the function never happens (just as a class is never destroyed, only objects/instances of it). This allows you to even return the pointer to a local lambda, as in the following example:

#include <iostream>

bool (*cpp_newbie())()
{
    auto a = +[]{return true;};
    return a;
}

int main()
{
    auto a = cpp_newbie();
    std::cout <<  std::boolalpha << a();
}

This seemed counterintuitive at first, but it became clear that lambda defines a type, and the object a in question is only a pointer to a "member function", so to speak.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.