Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to hold a std::lock_guard in the destructor?

I'm trying to decide if the following code is safe, or if it is UB and only happens to work well in this case (run it here):

#include <iostream>
#include <mutex>

struct Foo
{
  std::mutex mutex;
  ~Foo()
  {
    std::lock_guard<std::mutex> lock(mutex);
  }
};

int main() 
{
  {
    Foo foo;
  }
  std::cout << "everything seems to work fine...?" << std::endl;
}

Specifically, are we guaranteed anywhere that local variables defined inside the destructor will be destructed before the member variables are?

I found the following from cppreference.com, but it doesn't seem to fully answer my question:

Destruction sequence

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

like image 276
Jon McClung Avatar asked May 01 '19 21:05

Jon McClung


1 Answers

According to the standard in [class.dtor]/9,

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct non-variant non-static data members, the destructors for X’s non-virtual direct base classes and, if X is the type of the most derived class (15.6.2), its destructor calls the destructors for X’s virtual base classes. ...

This answers your question in the affirmative.

like image 199
Brian Bi Avatar answered Nov 15 '22 08:11

Brian Bi