$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2002-09-28 10:43:21
David Abrahams wrote:
[...]
> I don't really like scopeguard-like things for such jobs, since the danger
> of the above is that you have to remember to throw;, while you need to
> remember to cancel the scopeguard.
Yep. bool hypothetical_std::unwinding<T>(T*) would solve this, I guess.
Another approach might be something like:
http://groups.google.com/groups?selm=3D89CACB.12BB6122%40web.de
(Subject: Re: C++0x: Proposal for an additonal exception handling construct)
---
template< class _FwdIt >
class _Uninit_fill_cleanup {
_FwdIt const& m_First;
_FwdIt const& m_Last;
_FwdIt m_Next;
public:
_Uninit_fill_cleanup( _FwdIt const& _First, _FwdIt const& _Last ) :
m_First( _First ), m_Last( _Last ), m_Next( _First ) {
}
~_Uninit_fill_cleanup() {
if ( m_First != m_Last ) // if ( std::unwinding(this) ) // exceptional path
for (; m_First != m_Next; ++m_Next)
_Destroy(&*m_Next);
}
};
template< class _FwdIt, class _Tval >
inline void _Uninit_fill( _FwdIt _First, _FwdIt _Last, const _Tval& _Val ) {
_Uninit_fill_cleanup< _FwdIt > _Cleanup( _First, _Last );
for (; _First != _Last; ++_First)
_Construct(&*_First, _Val);
}
---
> It's an even trade.
Nope. An "even trade" isn't
catch(...) {
// Blah blah ...
throw;
}
but rather (well, "almost" -- unwinding aside):
catch(...) {
try {
// Blah blah ...
}
catch(...) { std::terminate(); }
throw;
}
> Of course if you factor in Mr. Terekhov's favorite issue
> (weird entaglements with not-really-C++ platform "exceptions"),
> the scopeguard might be a better solution.
And "action_on_propagation_of(<whatever>) {" might be even better,
I guess.
http://groups.google.com/groups?selm=3D89CACB.12BB6122%40web.de
(Subject: Re: C++0x: Proposal for an additonal exception handling construct)
---
Well, I'll admit that I'll have no problems with something like
template<class _FwdIt,
class _Tval> inline
void _Uninit_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val,
_Nonscalar_ptr_iterator_tag)
{ // copy _Val throughout raw [_First, _Last), arbitrary type
_FwdIt _Next = _First;
try {
for (; _First != _Last; ++_First)
_Construct(&*_First, _Val);
}
action_on_propagation_of(...) { /* THIS DOESN'T CATCH *UNEXPECTED* EXCEPTIONS */
/* THIS DOES RETHROW EXCEPTIONS AUTOMATICALLY */
/* NOTHING ELSE CAN BE THROWN FROM THIS SCOPE */
for (; _Next != _First; ++_Next)
_Destroy(&*_Next);
}
}
---
David Abrahams also wrote: <another article>
[...]
> > especially if you are trying to
> > write safe portable code (besides, they could be implemented as
> "really-C++"
> > exceptions on a given platform too).
>
> In that case, try/catch would be fine.
Nope. You wouldn't really want to ALWAYS have {partial} unwinding on
std::logic_error (unless you *really really* want it for some reason
that is beyond my understanding and/or imagination), would you? ;-)
Frankly, do YOU *also* kinda "doesn't seem to care"(*) with respect
to thread cancel/exit safety of your code (given that sort of "brain-
dead" *forced unwinding* IS adopted by many many C++ vendors/platforms
presently)? What am I missing, Mr. Abrahams?
regards,
alexander.
(*) http://groups.google.com/groups?threadm=3D8EEE36.C164536D%40web.de
("Subject: "PJP doesn't seem to care" ;-)" )