1

Lets say I have the following:

struct Foo
{
    Foo() : bar([&]{ doSomething();})
    std::function<void(void)> bar;
    void doSomething(){};
}

And lets say one thread is constantly calling the bar member of a Foo instance while another thread destructs the Foo instance. Is it possible that a call to bar will result in an invalid function call since the destructor of Foo is called first? Does the destructor of Foo invalidate member function calls before deallocation?

Edit: Sorry I should've been a little more specific, does calling doSomething become undefined before the destructor of bar is called?

Andreas Loanjoe
  • 2,205
  • 10
  • 26
  • Member variables exists in objects. If there's no object, how could the member variable exist? – Some programmer dude Oct 18 '17 at 08:20
  • 2
    It is your responsibility to ensure that no thread destroys an object while another thread is, or might be, using it. – David Schwartz Oct 18 '17 at 08:22
  • This is by the way the primary reason why an object cannot synchronize its own destruction. If you want implement 'destruction requests', that is, an object can be requested to destruct while concurrently handling other requests, this must be synchronized *externally*, not by the class itself. – ComicSansMS Oct 18 '17 at 08:33
  • 1
    "Scope" technically has another meaning. This is about lifetime. (The two are linked for local non-static variables in a function) – MSalters Oct 18 '17 at 08:38

2 Answers2

3

Is it possible that a call to bar will result in an invalid function call since the destructor of Foo is called first?

Yes, unless you make sure that doesn't happen.

Does the destructor of Foo invalidate member function calls before deallocation?

Yes. All references to that object and it's subobjects are invalidated as soon as the destructor is called.

Note that member function is something different from what you have. What you have is a function wrapper that is a member object. The distinction makes no difference to the answer though.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • To clarify: *Invalidate* here means that it is no longer valid to execute a member function as soon as the destructor starts. The language does not actually enforce this. It is *your* responsibility to ensure that this will never happen. If you fail to do this properly, the program is allowed to blow up in your face. – ComicSansMS Oct 18 '17 at 08:40
0

Member functions remain valid till the object is valid. When the object is destroyed, the member function is also destroyed and the object is destroyed when destructor is called. Thus the call in destructor invalidates the member functions. And if you call a member function after the destruction of object will cause undefined behavior. So, you need to make sure that no member function has been called after the object has been destroyed.

Naseef Chowdhury
  • 2,357
  • 3
  • 28
  • 52