1

After playing with placement new / delete, I came up with this piece of code, which, surprinsingly for me, compiles and runs (at least on gcc and clang):

int main()
{
    struct A{};
    A a;
    const A& b = a;
    b.~A();
}

I have tested more complex versions, for instance where the destructor of A calls members which are not const qualified. Is there a good reason for this ability to call destructor from const references?

  • 1
    If the destructor is not allowed to be called on `const` objects, how would you destroy that object otherwise? assume you have `const A;` in the program. Upon leaving the scope, *i.e.*, program exit in your example, its destructor is called. What would have happened if that were not allowed? – Arda Aytekin Mar 10 '18 at 11:43
  • That makes sense. I would have questioned a difference of treatment between implicit and explicit destructor calls... Anyway, another reason for using explicit destructor calls with care. – gcordonnier Mar 10 '18 at 11:50
  • 1
    I am not sure if you would like to call the destructor explicitly. Check the sentence "Note that calling a destructor directly for an ordinary object, such as a local variable, invokes undefined behavior when the destructor is called again, at the end of scope." in [cppreference](http://en.cppreference.com/w/cpp/language/destructor). – Arda Aytekin Mar 10 '18 at 11:54
  • @ArdaAytekin Yes, except from the usal case of casting from an aligned_storage. The question I had behind was whether I could cast it to const A&, the answer seems to be yes. – gcordonnier Mar 10 '18 at 12:00
  • Sorry. Since your example _is_ about the destruction of a local object from a const reference, I wanted to make a note. Otherwise, the answer below is also fine. It is not undefined behaviour unless someone else tries `a->~A();` for the second time. – Arda Aytekin Mar 10 '18 at 12:02

1 Answers1

0

Destructor is always implicitly const. You can delete objects thorough constant pointers and references. Since C++11, you can also erase container elements through const-iterators.

const A* a = new A();
delete a; // OK. Deletes pointed const object, implicitly calls destructor.
273K
  • 29,503
  • 10
  • 41
  • 64