Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trivial Destructibility and Necessity of Calling Destructor

Suppose there exists a type T such that std::is_trivially_destructable<T>::value == true, and suppose further that T is the value type of some vector class. When the vector's destructor is called, or the vector is assigned to another vector, it must destroy and deallocate its current storage. As T is trivially destructable, is it necessary that I call T's destructor?

Thanks for your help!

like image 633
void-pointer Avatar asked Aug 02 '12 15:08

void-pointer


3 Answers

According to the C++ Standard (section 3.8), you can end an object's lifetime by deallocating or reusing its storage. There's no need to call a destructor that does nothing. On the other hand, letting the compiler optimize away an empty destructor usually results in cleaner and simpler code. Only if you can save substantial additional work, such as iterating through the collection, would you want to special-case trivial destructors.

like image 59
Ben Voigt Avatar answered Sep 28 '22 12:09

Ben Voigt


libstdc++ (the standard library the gcc uses by default) applies precisely this optimisation:

  117   /**
  118    * Destroy a range of objects.  If the value_type of the object has
  119    * a trivial destructor, the compiler should optimize all of this
  120    * away, otherwise the objects' destructors must be invoked.
  121    */
  122   template<typename _ForwardIterator>
  123     inline void
  124     _Destroy(_ForwardIterator __first, _ForwardIterator __last)
  125     {
  126       typedef typename iterator_traits<_ForwardIterator>::value_type
  127                        _Value_type;
  128       std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
  129     __destroy(__first, __last);
  130     }

And the specialisation of std::_Destroy_aux for __has_trivial_destructor(_Value_type) == true:

  109   template<>
  110     struct _Destroy_aux<true>
  111     {
  112       template<typename _ForwardIterator>
  113         static void
  114         __destroy(_ForwardIterator, _ForwardIterator) { }
  115     };

I would expect that most other well-written standard library implementations do the same.

like image 21
ecatmur Avatar answered Sep 28 '22 11:09

ecatmur


No, you don't need to call the destructors explicitly. This will be done by the vector's destructor.

like image 22
Kiril Kirov Avatar answered Sep 28 '22 13:09

Kiril Kirov