Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference member binds to a temporary object whose life-time would be shorter than the lifetime of the constructed object

Tags:

c++

I'm getting the following compiler error trying to initialize a Context:

Reference member 'context' binds to a temporary object whose life-time would be shorter than the lifetime of the constructed object

. What temporary object is the compiler referring to? onEventInternal is static so the lifecycle can't be shorter

class Event {};

class Context {
    Context(int width, int height, void(*eventCallback)(Event&)) {}
};

class App {

    App(int w, int h): context{w, h, onEventInternal } {} // Error here! 

    static void onEventInternal(Event& event) {
        //event handling
    }
    
private:
    const Context& context;
};
like image 921
frankelot Avatar asked Oct 22 '25 04:10

frankelot


2 Answers

In the initialization section of your constructor:

context{w, h, onEventInternal }

This constructs a temporary Context object, stores a reference to this object in the context class member. So far so good. Then, as soon as the constructor returns this temporary object gets destroyed, leaving context as a reference to a destroyed object. Any subsequent use of this class member will result in undefined behavior.

context is a reference. It is not an object. That's what a reference means: it's a reference to some other object, somewhere.

The object that a reference refers to is a completely different and independent object.

You must construct this reference to refer to some other, existing object.

Your constructor does that, but it's a temporary object, and your compiler is smart enough to figure it out and warn you that you are at a high risk of demons flying out of your nose.

You will need to either change the class member to a standalone object, and not a reference, or pass a reference to the constructor, and have the constructor set the class member to the passed-in reference to some other object.

like image 68
Sam Varshavchik Avatar answered Oct 23 '25 20:10

Sam Varshavchik


What temporary object is the compiler referring to?

You're constructing a temporary Context in member initializer list and binding it to reference member context. The temporary will be destroyed immediately and left context dangled.

App(int w, int h): context{w, h, onEventInternal } {}
//                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// constructing a temporary Context and bind to context

class.base.init#8

A temporary expression bound to a reference member in a mem-initializer is ill-formed. [Example 5:

struct A {
  A() : v(42) { }   // error
  const int& v;
};

— end example]

like image 29
songyuanyao Avatar answered Oct 23 '25 20:10

songyuanyao