|
Boost : |
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" ;-)" )
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk