0

I'm confused about the nature of the variable capture part of a lambda expression.

void f1();
std::function<int()> f2;

int main() {
    f1();
    std::cout<<f2()<<endl;
}

void f1() {
    int x;
    f2 = [&]() {
        return x;
    };
}

Isn't x deconstructed before f2 is called?

3
  • I think that this is UB! Commented Oct 26, 2012 at 19:47
  • 4
    Please read this answer. Commented Oct 26, 2012 at 19:50
  • Things get even worse if you pass the lambda to a thread (async comes to mind). Commented Oct 26, 2012 at 20:04

2 Answers 2

4

Yes. You have successfully invoked undefined behavior. One possible outcome is that you get the value of x. Another is that the computer formats your hard drive, the program crashes, or the computer transforms into a robotic baker-assassin that feeds you cupcakes, mistakenly thinking you have celiac disease.

A safe variant of this might be:

int main() {
    f1(7);
    std::cout<<f2()<<endl;
}

void f1(int x) {
    std::shared_ptr<int> spX( new int(x) );
    f2 = [=]() {
        return *spX;
    };
}

or

void f1(int x) {
    f2 = [=]() {
        return x;
    };
}

(for an int, there is little reason not to store it by value: for a more complex type, you might want to avoid copying it around needlessly).

Note that the comment above explains this in a funnier way.

Now, some compilers will mark the stack with special values when you decrement it to catch exactly this kind of undefined behavior (and by catch, I mean make it more obvious to the programmer). But for the most part, invoking undefined behavior in C++ is possible.

Sign up to request clarification or add additional context in comments.

Comments

2

Isn't x deconstructed before f2 is called?

Yes, it is. Which means that the return x evaluates a dangling reference, which invokes undefined behavior.

In this instance, you might prefer to capture by value.

f2 = [x]() { return x; }

1 Comment

It's simply [x]. The [=] is for automatically catching unnamed external items by value.

Your Answer

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.