4

On this wikipedia page I have found the following sentence regarding closures in C++11:

C++11 closures can capture non-local variables by copy or by reference, but without extending their lifetime.

Does this mean that an existing closure might refer to a non-local variable that has already been de-allocated? In such a case, is there any special care / best practice that one has to follow when using captured non-local variables inside a C++ closure?

asked Aug 16, 2012 at 20:16
4
  • The same practices you follow when calling any function, surely. Commented Aug 16, 2012 at 20:57
  • I am not sure if this is sufficient. I could pass the closure as an argument to some object's method. That object could store the closure internally and then invoke it when its captured non-local variables have become invalid. Is this scenario possible? What would happen then? Commented Aug 16, 2012 at 21:01
  • @Giorgio: The code would invoke undefined behaviour. But how often is it that you don't know what the called function does with your passed functor? Commented Aug 16, 2012 at 21:06
  • @sellibitze: For that matter, also dereferencing an uninitialized pointer is undefined behaviour (normally leading to a crash), I do not have a problem with undefined behaviour. I am just trying to identify the problematic scenarios and how to avoid them. Commented Aug 16, 2012 at 21:12

1 Answer 1

4

Does this mean that an existing closure might refer to a non-local variable that has already been de-allocated?

Yes. Extending an object's life-time which was allocated on the stack beyond the execution of the outer function seems to be somewhere between unreasonable and impossible. Also, the compiler won't try to check whether such an extension is needed and magically allocate the object on the heap or something like this. As a programmer you have to be explicit about what is supposed to happen with respect to allocation. If you want to use the free store (aka heap), use the free store. There is nothing magical going on with lambdas. If you make your closure object store the address of some other object that used to live on the stack and you try to access it after it's gone, the behaviour is undefined.

any special care / best practice that one has to follow when using captured non-local variables inside a C++ closure?

Just make sure that your lambda does not capture by reference if the lambda object (or a copy of it) outlives the scope it (or the original) was created in. For example, using a lambda which captures by reference as argument to some of the algorithms you find in the algorithm header is perfectly fine.

answered Aug 16, 2012 at 21:04
7
  • Thanks, I think I get it. Intuitively I can consider the closure as an object (or, in particular, as a functor) with a reference member variable that is initialized to the captured non-local variable. Then I have the same risks I would have when moving around such an object. Commented Aug 16, 2012 at 21:38
  • "Extending an object's life-time which was allocated on the stack beyond the execution of the outer function seems to be somewhere between unreasonable and impossible.": In order to obtain this I guess I would have to allocate a smart pointer on the stack, and let the closure capture that. Then the object pointed to by the smart pointer would live as long as the closure is around. Commented Aug 16, 2012 at 21:42
  • @Giorgio: Your intuition is more than just reasonable; it's how lambda's must behave. The standard even says that the lambda must be an object, with a type - it's no magic construct. Commented Aug 17, 2012 at 7:22
  • @MSalters: Thanks. I am just trying to build the right intuition. AFAIK, lambdas in other languages behave differently, e.g. in Scheme data objects referenced by variables captured by a lambda continue to exist as long as the lambda exists. I just had to get the right C++ semantics into my head. Commented Aug 17, 2012 at 7:40
  • @Giorgio: That's because Scheme is GC. The behavior is again not specific to lambda's; Scheme objects are always only referenced by variables. In C++, variables can be objects or reference objects or point to objects. Commented Aug 17, 2012 at 8:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.