Why is the destructor called for an object that is not deleted?

This is gcc bug 57082.


Let’s go from the bottom up.

[dcl.fct.def.delete]/2:

A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.

Clearly, we’re not referring to ~A() explicitly. Are we referring to it implicitly? [class.dtor]/12:

A destructor is invoked implicitly

  • for a constructed object with static storage duration ([basic.stc.static]) at program termination ([basic.start.term]),
  • for a constructed object with thread storage duration ([basic.stc.thread]) at thread exit,
  • for a constructed object with automatic storage duration ([basic.stc.auto]) when the block in which an object is created exits ([stmt.dcl]),
  • for a constructed temporary object when its lifetime ends ([conv.rval], [class.temporary]).

Or in [expr.new]/20:

If the new-expression creates an array of objects of class type, the destructor is potentially invoked.

Do we have any of those things? No, there is no object with automatic, static, or thread storage duration here, nor is there a constructed temporary object, nor is our new-expression creating an array. There is only one object here at all, the one A with dynamic storage duration that we’re aggregate-initializing.

Since we’re neither explicitly nor implicitly referring to ~A(), we can’t be tripping over that rule. Hence, gcc bug. Note also that gcc accepts new A; and new A();, which have the same meaning as far as this rule is concerned.

Leave a Comment