Bwmat
Bwmat

Reputation: 4578

Is it really UB to access an object whose user-defined destructor has started, but not finished?

The question arose due to a discussion on Reddit, where a user told me, citing the standard's rules on object lifetime:

I'm pretty certain that it is technically UB to access an object, while it is being destructed.

I rely on this, for example, with classes that manage a background thread; I have their destructors signal the thread to exit and wait until it does, and that thread may access the object. Do I need to refactor my code?

Upvotes: 2

Views: 113

Answers (1)

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

No, it's well-defined.

If it were UB to access the object at all while its destructor is executing, that destructor would itself not be able to do anything with its own object. 😜


During execution of your destructor:

  • bases have not been destructed yet
  • the "current" object itself has not been destructed yet (and neither have its members)
  • some resources may have been released, if you did so in your destructor already
  • derived subobjects have been destructed
    • virtual function calls will safely refer to the "current" object, rather than these now-dead derived subobjects
    • dynamic_cast and typeid will do the same
    • you must not do any of these using a Derived*, though! Via a Base* or Current* is fine

Most of these rules are covered by [class.cdtor].


Though the object's lifetime does technically end with the beginning of the destructor "call", at this point you're in a kind of purgatory where [class.cdtor] takes over with the rules listed above:

[basic.life/7]: [..] after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. [..]

It's potentially an error-prone and confusing pattern, but it's not inherently incorrect. For your particular use case I'd even call it reasonably conventional.

Upvotes: 7

Related Questions