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.
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 forX
’s direct non-variant non-static data members, the destructors forX
’s non-virtual direct base classes and, ifX
is the type of the most derived class (15.6.2), its destructor calls the destructors forX
’s virtual base classes. ...
This answers your question in the affirmative.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With