Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order and point of calling destructor

Lets say I have two local objects. When the function returns, is it guaranteed which one will go out of the scope first?

For example:

I have a class like this:

class MutexLock
{
    /* Automatic unlocking when MutexLock leaves a scope */
    public:
      MutexLock (Mutex &m)      { M.lock();   }
      ~MutexLock(Mutex &m)      { M.unlock(); }
};

This is a very common trick used to automatically release the mutex when going out of scope. But what if I need two mutexes in the scope?

void *func(void *arg)
{ 
    MutexLock m1;
    MutexLock m2;

    do_work();

}  // m1 and m2 will get unlocked here. But in what order? m1 first or m2 first?

This really can't cause any deadlock. But there may be instances in which order of releasing the resource might be useful to the user. In that case is it important to be explicit rather than relying on destructors?

Also, can destruction be delayed by the compiler in any case? What I mean is

func()

{

     {
         foo f();
     } ---------> Can compiler choose to not destroy f here, rather do it at the time when func() is returning. 
}
like image 750
Saurabh Avatar asked May 15 '12 06:05

Saurabh


People also ask

What is the order of the constructor and destructor calls on the object?

Answer: C++ constructor call order will be from top to down that is from base class to derived class and c++ destructor call order will be in reverse order.

Which destructor is called first?

The destructor for a class object is called before destructors for members and bases are called. Destructors for nonstatic members are called before destructors for base classes are called. Destructors for nonvirtual base classes are called before destructors for virtual base classes are called.

Why is the destructor in reverse order?

Objects are always destroyed in reverse order of their creation. The reason for reverse order is, an object created later may use the previously created object.


3 Answers

// m1 and m2 will get unlocked here. But in what order? m1 first or m2 first?

The destructors will be called in the reverse order of construction: m2 then m1.

In that case is it important to be explicit rather than relying on destructors?

The order of destruction is well-specified so that you can rely on it.

Also, can destruction be delayed by the compiler in any case?

No. If it did, that would break a lot of RAII-based code (your MutexLock class is a very good example of that).

like image 154
NPE Avatar answered Sep 23 '22 02:09

NPE


In that case is it important to be explicit rather than relying on destructors?
No, it is not required.
The order of destruction of objects in a scope is well defined.
It is exact opposite of the order in which they were constructed.


Also, can destruction be delayed by the compiler in any case?
No.
The compiler cannot and that is the purpose of RAII. It provides the mechanism to implicitly clean & deallocate resources without any explicit manual effort on part of the programmer.
Your requirement of delaying the destruction is parallel to the very purpose of RAII, it calls for manual resource management.
If you need manual resource management you can have pointers allocated on heap through newand the objects pointed by them would be valid unless and until, you explicitly deallocate them through delete call and the order in which you call them.
Of-course, it is nor advisable nor encouraged to do so.

like image 23
Alok Save Avatar answered Sep 20 '22 02:09

Alok Save


The destruction happens in reverse order of construction: first m2 then m1.

Compiler can never delay object's lifetime behind scope end (}).

like image 27
hamstergene Avatar answered Sep 20 '22 02:09

hamstergene