Michal Sudolsky
2017-05-25 08:33:56 UTC
Hi,
Looking at code of PdfPainter destructor there is stated that throwing
exception in c++ destructors is not allowed but at bottom that
PODOFO_ASSERT is throwing exceptions. This basically means that throwing my
own exceptions between SetPage and FinishPage will results in abort because
podofo will throw during propagation of this exception as there was not
called FinishPage yet. So it is not possible to handle exceptions between
these two calls.
The fact is that throwing exceptions out of destructor is dangerous but can
be done normal exception handling inside destructor but must catch them
inside and not propagate them out.
PdfPainter::~PdfPainter()
PdfPainter::~PdfPainter()
{
FinishPage();
}
catch(...)
{
//if( m_pCanvas ) // but this will be always false here considering
}
As for reference see destructor of std filebuf (used by fstream):
template <class _CharT, class _Traits>
care about exception handling during close or if we do then we can
explicitly call close and so we can handle exceptions.
Looking at code of PdfPainter destructor there is stated that throwing
exception in c++ destructors is not allowed but at bottom that
PODOFO_ASSERT is throwing exceptions. This basically means that throwing my
own exceptions between SetPage and FinishPage will results in abort because
podofo will throw during propagation of this exception as there was not
called FinishPage yet. So it is not possible to handle exceptions between
these two calls.
The fact is that throwing exceptions out of destructor is dangerous but can
be done normal exception handling inside destructor but must catch them
inside and not propagate them out.
PdfPainter::~PdfPainter()
{
// Throwing exceptions in C++ destructors is not allowed.
// Just log the error.
// PODOFO_RAISE_LOGIC_IF( m_pCanvas, "FinishPage() has to be called
after a page is completed!" );
// Note that we can't do this for the user, since FinishPage() might
// throw and we can't safely have that in a dtor. That also means
// we can't throw here, but must abort.
if( m_pCanvas )
PdfError::LogMessage( eLogSeverity_Error,
"PdfPainter::~PdfPainter(): FinishPage()
has to be called after a page is completed!" );
PODOFO_ASSERT( !m_pCanvas );
}
Right solution would be something like this:// Throwing exceptions in C++ destructors is not allowed.
// Just log the error.
// PODOFO_RAISE_LOGIC_IF( m_pCanvas, "FinishPage() has to be called
after a page is completed!" );
// Note that we can't do this for the user, since FinishPage() might
// throw and we can't safely have that in a dtor. That also means
// we can't throw here, but must abort.
if( m_pCanvas )
PdfError::LogMessage( eLogSeverity_Error,
"PdfPainter::~PdfPainter(): FinishPage()
has to be called after a page is completed!" );
PODOFO_ASSERT( !m_pCanvas );
}
PdfPainter::~PdfPainter()
{
// Throwing exceptions *out of* C++ destructors is dangerous.
// Just log the error.
try// Throwing exceptions *out of* C++ destructors is dangerous.
// Just log the error.
{
FinishPage();
}
catch(...)
{
//if( m_pCanvas ) // but this will be always false here considering
implementation of FinishPage
// PdfError::LogMessage( eLogSeverity_Error,// "PdfPainter::~PdfPainter(): FinishPage()
has to be called after a page is completed!" );
}has to be called after a page is completed!" );
}
As for reference see destructor of std filebuf (used by fstream):
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>::~basic_filebuf()
{
try
{
close();
}
catch (...)
{
}
if (__owns_eb_)
delete [] __extbuf_;
if (__owns_ib_)
delete [] __intbuf_;
}
We can let to take care of closing file to destructor in case we do not{
try
{
close();
}
catch (...)
{
}
if (__owns_eb_)
delete [] __extbuf_;
if (__owns_ib_)
delete [] __intbuf_;
}
care about exception handling during close or if we do then we can
explicitly call close and so we can handle exceptions.