Home > database >  I'm learning C lambda function. Why does it have this output?
I'm learning C lambda function. Why does it have this output?

Time:04-29

This is my code

#include<iostream>
int* p = nullptr;
auto fun()
{
    int a = 1;
    p = &a;
    std::cout << &a << std::endl;
    auto z = [&a]() {std::cout << &a << "   "; a  ; std::cout << "lambda call " << a << std::endl; };
    return z;
}
int main()
{
    auto z = fun();
    std::cout << *p << "\n";
    z();
    z();
    
    fun()();
}

and the output is

0x7fffd10af15c
1
0x7fffd10af15c   lambda call 21880
0x7fffd10af15c   lambda call 21880
0x7fffd10af15c
0x7fffd10af15c   lambda call 21880

The version of my compiler is gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) Why do i have this output? Is it an undefined behavior?

CodePudding user response:

Why do i have this output?

The given program has undefined behavior since a is a local variable and will be destroyed once the function returns and so it(a) should not be referenced again.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash.

So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.

To solve this make sure that you don't reference the local variables out of their scope either by making them(a) a static or global.


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

CodePudding user response:

Yes, the problem is that a is a local variable in the fun function and gets destroyed by the time fun finishes. That means, the returned lambda z is referencing an area on the stack where a used to be, but now when z is called this area is used for something else (this is why you see 21880).

In order to avoid this problem you need to prevent a being destroyed when leaving fun's scope. One way is to declare a as a global variable, just like p. The other one is to make it a static variable.

  • Related