[Insight-developers] LightObject Destructor and Exception Safety

Brad King brad.king at kitware.com
Wed Apr 4 15:33:00 EDT 2007


Hello All,

The LightObject::~LightObject() destructor contains this code:

  /**
   * warn user if reference counting is on and the object is being
   * referenced by another object
   */
  if ( m_ReferenceCount > 0)
    {
    itkExceptionMacro(
      << "Trying to delete object with non-zero reference count.");
    }

A basic rule for exception safety is that destructors should not throw
exceptions.  I can explain why in more detail if anyone wants.  The
following problem we've encountered is one reason.

Consider a subclass of LightObject whose constructor throws an exception
because it fails to allocate some resource.  This is what happens:

1.) The LightObject constructor initializes m_ReferenceCount to 1.
    In the case that the whole object is constructed the NewMacro
    removes this extra reference before returning the smart pointer
    holding the object.
2.) The subclass constructor throws an exception.
    The partially-constructed object must be destroyed.
3.) The destructor of LightObject is called to destroy the piece
    of the object that was constructed before the exception was thrown.
4.) The above code throws another exception.
5.) In C++ when an exception is thrown during the handling of another
    exception the program terminates.

The real problem is that the destructor should not be throwing an
exception.  The symptom (#5) can be fixed by using
std::uncaught_exception to detect if an exception is already being handled:

  if(m_ReferenceCount > 0 && !std::uncaught_exception())
    {
    itkExceptionMacro(
      << "Trying to delete object with non-zero reference count.");
    }

However, I think we should come up with an alternative means of
reporting the early destruction of an object under normal circumstances.

Ideas?
-Brad


More information about the Insight-developers mailing list