Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime of const references bound to destroyed stack variable

I'm wondering if it's by chance a pointer to const reference bound to a destroyed stack variable can be working.
I read const reference lifetime is extended on rvalues, so this is "normal" const reference works but at the end of the ctor of Storage ref should be destroyed, isn't it ?
Does const reference lifetime is also extended because I retrieved it's address in a pointer or is this pure luck ?

Live example

#include <iostream>

class Storage
{
public:
    Storage(const int& ref)
    {
        p = &ref;
    }

    const int* Get() const
    {
        return p;
    }

private:    
    const int* p;
};

int main()
{
    Storage* s = nullptr;

    {
        int someValue = 42;
        std::cout << &someValue << std::endl;
        s = new Storage(someValue);
    }

    const int* p = s->Get();
    std::cout << p << std::endl;
    std::cout << *p << std::endl;
}

It's also working with a struct Live example

#include <iostream>

struct Dummy
{   
    int value;
};

class Storage
{
public:
    Storage(const Dummy& ref)
    {
        p = &ref; // Get address of const reference
    }

    const Dummy* Get() const
    {
        return p;
    }

private:    
    const Dummy* p;
};

int main()
{
    Storage* s = nullptr;

    {
        Dummy dummy;
        dummy.value = 42;
        std::cout << &dummy << std::endl;
        s = new Storage(dummy);
    }

    const Dummy* p = s->Get();
    std::cout << p << std::endl;
    std::cout << p->value << std::endl;
}
like image 667
Richard Dally Avatar asked Jan 08 '23 20:01

Richard Dally


1 Answers

Your s variable indeed has a dangling pointer as someValue has fallen out of scope. Your code therefore exhibits undefined behavior.

Your comment about "const reference lifetime is extended on rvalues" is true in some circumstances, but someValue is an lvalue.

like image 129
Cory Kramer Avatar answered Jan 24 '23 04:01

Cory Kramer