Lambda in for loop - static variable

Viewed 155

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:

  1. each iteration of the loop new class with a functor operator will be created (since every time it captures new local variable)
  2. initialization of static variable s will happen once every iteration since it is a different lambda

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.

1 Answers

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.

Related