Dear stackoverflow community!
Recently, I was hunting for a bug at work, which led me to the following piece of code I wrote myself. Here is a simplified version:
int main()
{
for(int i = 0; i < 5; ++i)
{
int j = i + 1;
auto k = [j](){
static int s{j};
cout << s << endl;
};
k();
}
}
I know that it might look silly, but there was some logic behind it (since I was using this lambda to connect to a slot in QT framework)
Here are my expectations:
However, I was wrong. After compiling with GCC 9.3.0 I got the following output:
1
1
1
1
1
Does it mean that 1 "hidden" functor is created once for every iteration of the loop (then a static is initialized during the first iteration of the loop)? Does it then mean that we should avoid nasty non-constexpr static variables in lambdas? Where am I wrong?
Thanks for you time, looking forward to any replies.
Whenever the function is called, count will have the last value assigned to it. You can also use static in this fashion to prevent a variable from being reinitialized inside a loop.
A lambda or anonymous method may have a static modifier. The static modifier indicates that the lambda or anonymous method is a static anonymous function. A static anonymous function cannot capture state from the enclosing scope.
Think of a lambda expression as a terse recipe to define a class that overloads the call operator()
. In your case:
struct LambdaEquivalent {
int j;
auto operator() const
{
static int s{j};
cout << s << endl;
}
};
And you loop then is
for(int i = 0; i < 5; ++i)
{
int j = i + 1;
LambdaEquivalent k{j};
k()
}
This illustrates that any local static data in the body of a lambda expression is nothing but local static data in a member function - and that is initialized exactly once. It's a good thing that both cases behave identically, handling it differently could be very confusing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With