c++lambdascopereferencename-binding

Why does lambda capture by reference is still working with dangling references?


To my surprise, the following C++ program:

#include <iostream>
#include <functional>


int main() {
    std::function<void(void)> f;
    {
        int x = 1;
        f = [&x]() { std::cout << x; };
    }
    //std::cout << x;  // error: use of undeclared identifier 'x'
    f();               // no error!
    return 0;
}

outputs:

1

I would have expected the same output as the output that I get when uncommenting the commented line:

error: use of undeclared identifier 'x'

since the lambda f captured the automatic variable x by reference (not by value) and x is not in context at the point of call f() (so x in f body is a dangling reference).

Why does lambda capture by reference is still working with dangling references?


Solution

  • Why does lambda capture by reference is still working with dangling references?

    This is undefined behaviour so there can be any reason for why it is working the way it is working. If you compile the code with:

    Try here: https://godbolt.org/z/5dd5sM

    clang++ -O3 -fsanitize=address
    

    You will immediately get:

    ERROR: AddressSanitizer: stack-use-after-scope on address ....
    READ of size 4...