Return lambda by capturing a local variable

Today I met very unintuitive behavior (at least for me) in C ++ 11 lambdas. This code is as follows:

#include <stdio.h> auto sum(int x) { return [&x](int y) { return x + y; }; } int main() { int a = sum(2)(3); printf("%d\n",a); } 

Instead of printing 5, it prints gibberish. In fact, at least in my version of GCC, if I turn on the OO optimization flag, it actually prints 5. Since the output depends on the compiler optimization level, this behavior is undefined. After a while, I think I realized what was going on.

When the sum function is called, the stack variable corresponding to the argument x is set to 2, then the sum function is returned, and this stack variable can be overwritten by everything that the compiler must execute there in order to execute the following code, and by the time the lambda is in the final the result will be executed, the place where x no longer holds 2, and the program adds 3 to an arbitrary integer.

Is there any elegant way to do currying in C ++, ensuring that the variable is captured correctly?

+5
source share
1 answer

int x has a limited lifetime. References to automatic storage variables (what you call a "stack") are only valid for the life of the variable. In this case, only until the end of the stack frame (scope) where the variable exists, or functions for the function arguments.

[&] captures any specified ("local") variable by reference, except for this (which is fixed by value if used or implicitly used). [=] captures any given variable by value. [x] will explicitly display x and [&x] by reference. In C ++ 17, [*this] also works.

There is also [x=std::move(x)] or [blah=expression] .

In general, if the lambda moves to the current area, do not use [&] : indicate what you captured.

+8
source

All Articles