Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does lambda capture local static variable?

Tags:

c++

c++11

In below code I do not specify any capture mode, yet some_static is visible inside closure. So the question is whether it is actually captured, or maybe somehow referenced in other way.

Bonus question is whether compiler is allowed to turn such lambda into a free function instead of closure - that would be possible as no capture list is specified.

std::vector<std::function<bool(int)>> filters;

int main()
{
    static int some_static = 1;
    filters.emplace_back([](int){
      return some_static == 2;
    });
}
like image 240
mike Avatar asked Apr 02 '17 14:04

mike


2 Answers

You don't need to capture global or static variables. Only automatic variables have to be captured if you want to use them.

Because of that, yes, you can convert such lambda to a function pointer.


Cppreference:

The identifier in any capture without an initializer (other than the this-capture) is looked up using usual unqualified name lookup in the reaching scope of the lambda. The result of the lookup must be a variable with automatic storage duration declared in the reaching scope.

(emphasis mine)

"To capture" means to put a copy or a reference to a variable into a lambda object itself.

Global and static variables have fixed memory location. You don't need to store copies or references to them to use them since their location is known at compile time and doesn't change.

(If you really want to have a copy of a global or static variable, you can create it using named capture from C++14, which lets you create a custom member variable in a lambda object. But such capture is not necessary if you just want to use that global / static variable.)

Automatic variables, on the other hand, don't have a fixed location. Multiple lambdas created at the exact same place could refer to different automatic variables. Because of that, a lambda object has to capture such variable - which means to contain either a reference to used automatic variable or a copy of it.

like image 127
HolyBlackCat Avatar answered Sep 25 '22 19:09

HolyBlackCat


Generally a lambda is implemented as a class with variables and a single member function (behind the scenes). However when it captures a static this isn't necessary - because the code is generated by the compiler, it has no scope rules, and it can simply access the static directly. So a lambda that captures only static variables will have an empty class member list, and might well be optimised to a simple function pointer.

like image 28
Malcolm McLean Avatar answered Sep 24 '22 19:09

Malcolm McLean