0

If I initalize a lambda like this ...

void f()
{
    int i;
    static
    auto lambda = [&i]()
    {
        cout << &i << endl;
    };
    // volatile to prevent inline-optimizations
    function<void()> fn( lambda ), *volatile pFn = &fn;
    (*pFn)();
}

... the lambda is initialized once with the first function-call (aside tha this doesn't make sense since &i could be different for each fn()-call but remain static for the lambda). But does this happen synchronized, i.e. do I not have to guard this initialization myself with a mutex ?

Bonita Montero
  • 2,817
  • 9
  • 22
  • _"...If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once ..."_ see https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables and as you note capturing `i` by reference does not make sense. – Richard Critten Sep 11 '21 at 08:31
  • `does this happen synchronized` synchronized... with? `I not have to guard this initialization myself with a mutex ?` How would a mutex help? Does https://stackoverflow.com/questions/8102125/is-local-static-variable-initialization-thread-safe-in-c11 answer your question? I do not know, if you ask if lambda will be "synchronized" with `i` variable address and lambda will have the address of `i` each call, __or__ if you ask about what if multiple threads execute the function concurrently and how will the initialization work then. Please kindly add additional details. – KamilCuk Sep 11 '21 at 08:37
  • 1
    Since static lambda captures non-static local variable by reference it will end up with dangling reference. – user7860670 Sep 11 '21 at 08:39
  • @user That's what I also said: the reference won't be valid for future function-calls and the whole thing doesn't make practical sense, but it's interesting in theory. – Bonita Montero Sep 11 '21 at 08:44
  • With MSVC I just found that before and after the static initialization two functions are called: _Init_thread_header and _Init_thread_footer. These functions call EnterCriticalSection() and LeaveCriticalSection. So at least with MSVC all this happens synchronized. – Bonita Montero Sep 11 '21 at 08:53
  • _"... interesting in theory..."_ it's been guaranteed since C++11. – Richard Critten Sep 11 '21 at 08:59
  • the second call invokes UB anyhow, so it doesnt matter whether it is synchonized or not. Why not use `static int i;` ? – 463035818_is_not_an_ai Sep 11 '21 at 09:28
  • Yes since C++11 we have : Static variables with block scope will be created exactly once. (even in multithreaded environments). I use that quite often. – Pepijn Kramer Sep 11 '21 at 09:29
  • @463035818_is_not_a_number - I was wanting to say UB on the 2nd call but am unsure if printing the address of a dangling reference is UB or not? – Richard Critten Sep 11 '21 at 09:55
  • No, it's just printing the address and not referencing i, and that's not UB. –  Sep 11 '21 at 10:07

0 Answers0