Topic: detecting stack unwinding


Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Wed, 22 Aug 2007 11:08:41 CST
Raw View
On 22    , 00:38, Bronek Kozicki <b...@spam-trap-cop.net> wrote:
> Roman.Perepeli...@gmail.com wrote:
> > Could you explain? Isn't it possible to do something like this?
>
> > struct guard: private boost::noncopyable
> > {
> >     ~guard()
> >     {
> >         if (std::stack_unwinding())
> >             rollback(); // nothrow
> >     }
> > };
>
> it is possible, except that it will sometimes rollback when it should
> commit, eg. when transaction itself is started inside a destructor. More
> on this herehttp://gotw.ca/gotw/047.htm
>
> B.

It won't. Note the use of std::stack_unwinding() instead of
std::uncought_exception().
The difference between them is that uncought_exception is useless,
while
stack_unwinding is not. Another difference: uncought_exception is not
in standard.

Roman Perepelitsa.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@interia.pl>
Date: Wed, 22 Aug 2007 11:09:14 CST
Raw View
Interestingly, gotw.ca also seams to have employed this technique.
Have a look at the Janitor class in http://gotw.ca/gotw/008.htm

Also, solutions like BOOST_SCOPE_EXIT
(http://194.6.223.221/~nasonov/scope_exit-0.04/libs/scope_exit/doc/
html/index.html) seam to long for the feature.

I believe to have found a partial solution to the problem somewhere in
the web. I cannot recall it right now where it was. It was using
Petruscu's ScopeGuard and a for loop combined in a macro:

class Rollback : boost::noncopyable
{
    std::function< void() > fun;

public:

    explicit Rollback( std::function< void() > const& fun ) : fun(fun)
{}
    ~Rollback() { if( armed() ) fun(); }
    void disarm() { fun.clear(); }
    bool armed() const { return !fun.empty(); }
};


#define GUARDED( _EXPR )                                   \
    for( Rollback rb(_EXPR) ; rb.armed() ; rb.disarm() )  \


The trick here is the increment part of the for-loop that disarms the
guard and may be skipped if the body throws an exception. The macro
also protects us against creating a temporary object instead of
automatic one. It can be used like:

void addEverywhere( Elem const& elem )
{
    vec1.push_back( elem );
    GUARDED(( bind(mem_fn(std::vector<Elem>::pop_back), vec1) ))
    {
        collection1.insert( elem );

        GUARDED(( bind(mem_fn(Collection::erase), set1, elem) ))
        {
            vec2.push_back( elem );
        }
    }
}

And if lambdas make it into the standard this could be changed (after
tuning the macro a bit to):

void addEverywhere( Elem const& elem )
{
    vec1.push_back( elem );
    GUARDED(( vec1.pop_back() ))
    {
        collection1.insert( elem );

        GUARDED(( set1.erase(elem) ))
        {
            vec2.push_back( elem );
        }
    }
}

Of course using a macro already suggests that we are missing something
in the language, and, as usually with macros, unexpected things can
happen like in:

while( ... )
{
    GUARDED(( ... ))
    {
        ...
        break; // break what?
    }
}

-------------
&rzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Wed, 22 Aug 2007 19:40:58 GMT
Raw View
Roman.Perepelitsa@gmail.com wrote:
> On 22    , 00:38, Bronek Kozicki <b...@spam-trap-cop.net> wrote:
>> Roman.Perepeli...@gmail.com wrote:
>>> Could you explain? Isn't it possible to do something like this?
>>> struct guard: private boost::noncopyable
>>> {
>>>     ~guard()
>>>     {
>>>         if (std::stack_unwinding())
>>>             rollback(); // nothrow
>>>     }
>>> };
>> it is possible, except that it will sometimes rollback when it should
>> commit, eg. when transaction itself is started inside a destructor. More
>> on this herehttp://gotw.ca/gotw/047.htm
>>
>> B.
>
> It won't. Note the use of std::stack_unwinding() instead of
> std::uncought_exception().
> The difference between them is that uncought_exception is useless,
> while
> stack_unwinding is not. Another difference: uncought_exception is not
> in standard.

I cannot find stack_unwinding neither in ISO 14882:2003 nor in the
current draft, N2315.

I thought that you meant to use uncaught_exception, which is in the
standard (15.5.3). As to "uncought_exception" I do not know where this
name came from.

Could you pls provide more details on semantics of stack_unwinding as
used above? I have hard time trying to imagine how it will allow for
commit (in the present design) in the situation when the transaction is
created locally inside a destructor (of an entity of higher software
layer), while the destructor is called while unwinding. Such a
transaction can be used to mark process in the database as "Failed" and
I assure this is not purely theoretical situation.


B.

--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Wed, 22 Aug 2007 19:41:22 GMT
Raw View
restor wrote:
> Of course using a macro already suggests that we are missing something
> in the language, and, as usually with macros, unexpected things can
> happen like in:

yeah, it would be much simpler if the interface of original transaction
class was enriched with explicit "commit" (and preferably "rollback")
functions. We could simply write (on the lap):

class transaction_owner
{ // all private
   ~transaction_owner() {}
   virtual void begin_transaction() = 0;
   virtual void commit_transaction() = 0;
   // following is no-op if already commited and never throws
   virtual void rollback_transaction() = 0;
   friend class transaction; // to improve encapsulation
};

class transaction : boost::noncopyable
{
   transaction_owner& to_;
public:
   explicit transaction(transaction_owner& to) : to_(to)
     {to_.begin_transaction();}
   void commit() {to_.commit_transaction();}
   void rollback() (to_.rollback_transaction();}
   ~transaction() {to_.rollback_transaction();}
};

class connection : public transaction_owner
                  , public boost::noncopyable
{
   virtual void begin_transaction();
   virtual void commit_transaction();
   virtual void rollback_transaction();
// . . .
};

   connection& conn = // . . .
   transaction t(conn);
   conn.execute(statement1);
   conn.execute(statement2);
   t.commit();


. and above will work in all situations, including nested loops or
inside destructor called during stack unwinding.


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Thu, 23 Aug 2007 09:52:53 CST
Raw View
> b...@spam-trap-cop.net (Bronek Kozicki) wrote:
> Roman.Perepeli...@gmail.com wrote:
> > On 22    , 00:38, Bronek Kozicki <b...@spam-trap-cop.net> wrote:
> >> Roman.Perepeli...@gmail.com wrote:
> >>> Could you explain? Isn't it possible to do something like this?
> >>> struct guard: private boost::noncopyable
> >>> {
> >>>     ~guard()
> >>>     {
> >>>         if (std::stack_unwinding())
> >>>             rollback(); // nothrow
> >>>     }
> >>> };
> >> it is possible, except that it will sometimes rollback when it should
> >> commit, eg. when transaction itself is started inside a destructor. More
> >> on this herehttp://gotw.ca/gotw/047.htm
>
> >> B.
>
> > It won't. Note the use of std::stack_unwinding() instead of
> > std::uncought_exception().
> > The difference between them is that uncought_exception is useless,
> > while
> > stack_unwinding is not. Another difference: uncought_exception is not
> > in standard.
>
> I cannot find stack_unwinding neither in ISO 14882:2003 nor in the
> current draft, N2315.
>
> I thought that you meant to use uncaught_exception, which is in the
> standard (15.5.3). As to "uncought_exception" I do not know where this
> name came from.
>
> Could you pls provide more details on semantics of stack_unwinding as
> used above? I have hard time trying to imagine how it will allow for
> commit (in the present design) in the situation when the transaction is
> created locally inside a destructor (of an entity of higher software
> layer), while the destructor is called while unwinding. Such a
> transaction can be used to mark process in the database as "Failed" and
> I assure this is not purely theoretical situation.

Please see the first post in this thread.
http://groups.google.ru/group/comp.std.c++/browse_thread/thread/1901e3fbdffba62a/b36150b06ae1ebd0

std::stack_unwinding() returns true iif it is called from the
destructor that
is called as a result of stack unwinding due to exception. You can
find
example of usage in the thread mentioned above.

I don't think stack_unwinding is good name for such function. I use it
because OP used this name. But regardless of its name I think it's
useful.

Roman Perepelitsa.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@interia.pl>
Date: Thu, 23 Aug 2007 09:53:44 CST
Raw View
On 22 Aug, 21:40, b...@spam-trap-cop.net (Bronek Kozicki) wrote:
> Roman.Perepeli...@gmail.com wrote:
> > On 22    , 00:38, Bronek Kozicki <b...@spam-trap-cop.net> wrote:
> >> Roman.Perepeli...@gmail.com wrote:
> >>> Could you explain? Isn't it possible to do something like this?
> >>> struct guard: private boost::noncopyable
> >>> {
> >>>     ~guard()
> >>>     {
> >>>         if (std::stack_unwinding())
> >>>             rollback(); // nothrow
> >>>     }
> >>> };
> >> it is possible, except that it will sometimes rollback when it should
> >> commit, eg. when transaction itself is started inside a destructor. More
> >> on this herehttp://gotw.ca/gotw/047.htm
>
> >> B.
>
> > It won't. Note the use of std::stack_unwinding() instead of
> > std::uncought_exception().
> > The difference between them is that uncought_exception is useless,
> > while
> > stack_unwinding is not. Another difference: uncought_exception is not
> > in standard.
>
> I cannot find stack_unwinding neither in ISO 14882:2003 nor in the
> current draft, N2315.
>
> I thought that you meant to use uncaught_exception, which is in the
> standard (15.5.3). As to "uncought_exception" I do not know where this
> name came from.
>
> Could you pls provide more details on semantics of stack_unwinding as
> used above? I have hard time trying to imagine how it will allow for
> commit (in the present design) in the situation when the transaction is
> created locally inside a destructor (of an entity of higher software
> layer), while the destructor is called while unwinding. Such a
> transaction can be used to mark process in the database as "Failed" and
> I assure this is not purely theoretical situation.

std::stack_unwinding is not in the standard. It is the proposal for
the new function - an alternative to std::uncaught_exception -  that I
started this discussion with. I thought about differentiating between
two modes in which destructors are called:

struct Inner {
    ~Inner() { assert( std::stack_unwinding() == false ); } //
contrary to uncaught_exception

};

struct Outer {
    ~Outer() {
        assert( std::stack_unwinding() == true ); // like
uncaught_exception
        Inner in;
    }
};

void fun() {
        Outer out;
        throw std::exception();
}

However, when I think about detailed semantics thereof I start to
think that it is not easy to neither to provide it nor to implement
it. Basically it would give the answer that makes the code:

~Guard() {
    if( std::stack_unwinding() )
        rollback();
}

always work correctly.
Now suppose we have this stack_unwinding function, class transaction
from your example could be defined as:

class transaction : boost::noncopyable
{
   transaction_owner& to_;
public:
   explicit transaction(transaction_owner& to) : to_(to)
     {to_.begin_transaction();}

   ~transaction() {
      if( std::stack_unwinding() )
         to_.rollback_transaction();
      else
         to_.commit_transaction();
   }
};

and you would use it:

fun() {
   connection& conn = // . . .
   transaction t(conn);
   conn.execute(statement1);
   conn.execute(statement2);
   // no commit needed
}

Basically, you could say that I am fighting for this one line commit
code.
&rzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Thu, 23 Aug 2007 19:15:36 GMT
Raw View
Roman.Perepelitsa@gmail.com wrote:
> Please see the first post in this thread.
> http://groups.google.ru/group/comp.std.c++/browse_thread/thread/1901e3fbdffba62a/b36150b06ae1ebd0

that is current thread, no need to send me to Google news archive.

> std::stack_unwinding() returns true iif it is called from the
> destructor that
> is called as a result of stack unwinding due to exception. You can
> find
> example of usage in the thread mentioned above.

but I still do not understand how, in the proposed design, it will allow
for commit while transaction is owned by the destructor ran during stack
unwinding. Care to clarify?


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Thu, 23 Aug 2007 19:16:27 GMT
Raw View
restor wrote:
> std::stack_unwinding is not in the standard. It is the proposal for
> the new function - an alternative to std::uncaught_exception -  that I
> started this discussion with. I thought about differentiating between
> two modes in which destructors are called:

I think there are at least few more "modes" in which object can be
destroyed.
- implicit due to stack unwinding;
- implicit due to object on stack leaving scope;
- explicit due to delete expression being executed;
- destructor called explicitly in user code;
- there are sub-object being destroyed, which can be any of above;
- and finally there are sub-objects of a partially constructed object
being destroyed due to exception being thrown during construction

> struct Outer {
>     ~Outer() {
>         assert( std::stack_unwinding() == true ); // like
> uncaught_exception
>         Inner in;
>     }
> };

> However, when I think about detailed semantics thereof I start to
> think that it is not easy to neither to provide it nor to implement
> it. Basically it would give the answer that makes the code:

yes, it would require some compiler magic, not to mention that the
semantics will be quite difficult (if at all possible) to define
clearly. And you definitely need to clearly define this semantics if you
are about to propose something.

> Basically, you could say that I am fighting for this one line commit
> code.

I'd suggest that you come up with better motivating example and show
something that is:
- beneficial to the language users and at the same time
- there is no workaround using existing language features.
Explicit call to "commit" is such a workaround, thus you need to come
with something better.


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: frege <gottlobfrege@gmail.com>
Date: Thu, 23 Aug 2007 17:41:40 CST
Raw View
On Aug 23, 3:16 pm, b...@spam-trap-cop.net (Bronek Kozicki) wrote:

> yes, it would require some compiler magic, not to mention that the
> semantics will be quite difficult (if at all possible) to define
> clearly. And you definitely need to clearly define this semantics if you
> are about to propose something.
>

I do think that it is interesting that the compiler (or, actually its
runtime component) knows when to call terminate because of a 'double
throw', but that we can't detect if the throw will cause the
terminate.  If the compiler knows, why don't we?  Should we have
access to that info?

Although I'm not sure 'std::throw_will_terminate' solves the commit
problem or not.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@interia.pl>
Date: Fri, 24 Aug 2007 09:44:34 CST
Raw View
> yes, it would require some compiler magic, not to mention that the
> semantics will be quite difficult (if at all possible) to define
> clearly. And you definitely need to clearly define this semantics if you
> are about to propose something.

> I'd suggest that you come up with better motivating example and show
> something that is:
> - beneficial to the language users and at the same time
> - there is no workaround using existing language features.
> Explicit call to "commit" is such a workaround, thus you need to come
> with something better.

Your approach is more clear.

As to the semantics:
bool function is indeed one that is too problematic. And I didn't
realize this at first. However I still think that stack unwinding
detection (at least for commit purpose) may be easy to implement with
different approach. It was proposed 9 years ago by Christopher
Eltschka in this group (subject was "Exception Handling" (I don't know
how to paste link into this text)). The solution was to make
std::uncaught_exception return number of currently handled exceptions
rather than bool saying if there is at least one. This would spoil no
code that uses std::uncaught_exception in the boolean context, but the
difference between the uncaught_exception value during the destruction
and during the construction would give the answer that I am after.

Here's the link:
http://groups.google.co.uk/group/comp.std.c++/browse_thread/thread/3f19c914c90d926a/5a2de68bbeab467f?lnk=gst&q=uncaught_exception&rnum=1&hl=en#

As to rationale:
One is to make the auto commit or auto cleanup.
If we say the destructor is a cleaner substitute for "finally". The
one above would be cleaner alternative to catch(...){throw;} and a bit
better than the "Commit" you showed. Cleaner because simply using type
"transaction" would guarantee that commit (and if impossible,
rollback) will take place, which will resolve some inadvertent
rollbacks.

I didn't provide much better rationale. I think I provided cleaner
solution. If you still think that change effort overweights the
benefits than perhaps it is not worth it.

&rzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Fri, 24 Aug 2007 14:52:40 GMT
Raw View
frege wrote:
> I do think that it is interesting that the compiler (or, actually its
> runtime component) knows when to call terminate because of a 'double
> throw',

compiler does not need to know it. It is only when the exeption leaks
(not when it's thrown, according to the current understanding of the
standard intent) when the process is terminated. In other words, it is
always safe to throw an exception inside destructor, it's only unsafe to
  leak it.


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@interia.pl>
Date: Mon, 20 Aug 2007 00:55:20 CST
Raw View
Hi,
I wonder if we could have another exception handling special function
to detect if we are in stack unwinding mode? I have a particular
application in mind: a transaction rollback. I would like to have a
generic rollback mechanism like:


class Guard : NoCopy, NoHeap
{
    std::function<void()> fun;

public:
    template< Callback Fun > Guard( Fun const& fun ) : fun(fun) {}

    ~Guard() throw() {
        if( needRollback() )
            try{ fun(); } catch(...){};
    }
};

The problem here is how to implement the function needRollback that
would tell as if the piece of code executing now is caused directly by
stack unwinding as opposed to regular stack operation.
Function std::uncaught_exception isn't necessarily a good choice as it
desn't give us the answer we want in the nested try blocks entered
during stack unwinding.
In  http://www.ddj.com/cpp/184403758  the autor of the ScopeGuard
needs the user to manually call Dismiss function, which seams too
verbose if only we had something like std::stack_unwinding. It seams
very easy for compiler vendors to implement and the rollback problem
seams a rather popular popular.

&rzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Bronek Kozicki <brok@spam-trap-cop.net>
Date: Mon, 20 Aug 2007 09:19:24 CST
Raw View
restor wrote:
> I wonder if we could have another exception handling special function
> to detect if we are in stack unwinding mode? I have a particular

there is no reliable way to do it. I would suggest to add function
   void commit();
to your interface, and assume we are in rollback mode if it has not been
called before destruction.


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@pacbell.net>
Date: Tue, 21 Aug 2007 08:18:23 CST
Raw View
On Aug 19, 11:55 pm, restor <akrze...@interia.pl> wrote:

> The problem here is how to implement the function needRollback that
> would tell as if the piece of code executing now is caused directly by
> stack unwinding as opposed to regular stack operation.
> Function std::uncaught_exception isn't necessarily a good choice as it
> desn't give us the answer we want in the nested try blocks entered
> during stack unwinding.

I'm not clear on that last point: What is the answer that you want
uncaught_exception() to give within the nested try blocks - and why do
you want that particular answer?

Greg



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Tue, 21 Aug 2007 09:34:54 CST
Raw View
> Bronek Kozicki <b...@spam-trap-cop.net> wrote:
> restor wrote:
> > I wonder if we could have another exception handling special function
> > to detect if we are in stack unwinding mode? I have a particular
>
> there is no reliable way to do it. I would suggest to add function
>    void commit();
> to your interface, and assume we are in rollback mode if it has not been
> called before destruction.
>
> B.

Could you explain? Isn't it possible to do something like this?

struct guard: private boost::noncopyable
{
    ~guard()
    {
        if (std::stack_unwinding())
            rollback(); // nothrow
    }
};

Or even this:
~guard()
{
    if (std::stack_unwinding())
        rollback(); // nothrow
    else
        commit(); // can throw
}

Roman Perepelitsa.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: frege <gottlobfrege@gmail.com>
Date: Tue, 21 Aug 2007 11:40:28 CST
Raw View
On Aug 21, 10:18 am, Greg Herlihy <gre...@pacbell.net> wrote:
> On Aug 19, 11:55 pm, restor <akrze...@interia.pl> wrote:
>
> > The problem here is how to implement the function needRollback that
> > would tell as if the piece of code executing now is caused directly by
> > stack unwinding as opposed to regular stack operation.
> > Function std::uncaught_exception isn't necessarily a good choice as it
> > desn't give us the answer we want in the nested try blocks entered
> > during stack unwinding.
>
> I'm not clear on that last point: What is the answer that you want
> uncaught_exception() to give within the nested try blocks - and why do
> you want that particular answer?
>
> Greg
>


I think this is in reference to Guru of the Week #47 and 66 (http://
gotw.ca/gotw/047.htm and http://gotw.ca/gotw/066.htm).
The articles could definitely help the discussion either way.

P.S.  I've also come across a couple of places where I'd like to know
whether throwing would lead to terminate.  I understand Sutter's
reasoning for why this is typically "Immoral", but there are always
strange examples where it would be useful.

Tony

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: restor <akrzemi1@interia.pl>
Date: Tue, 21 Aug 2007 11:40:28 CST
Raw View
> > The problem here is how to implement the function needRollback that
> > would tell as if the piece of code executing now is caused directly by
> > stack unwinding as opposed to regular stack operation.
> > Function std::uncaught_exception isn't necessarily a good choice as it
> > desn't give us the answer we want in the nested try blocks entered
> > during stack unwinding.
>
> I'm not clear on that last point: What is the answer that you want
> uncaught_exception() to give within the nested try blocks - and why do
> you want that particular answer?

Let me give you an example:
-----------------------------------------------

struct Inner {
    ~Inner() { std::cout << std::uncaught_exception() << std::endl; }
};

struct Outer {
    ~Outer() { try{ Inner in; } catch(...) {}; }
};

int main() {
    try{
        Outer out;
        throw int();
    } catch( ... ) {}
}

---------------------------------------
This program outputs "1". I would like std::stack_unwinding to make
this program return "0".
I realize that what I want std::stack_unwinding to do is NOT saying
"is it safe to throw". I would just need it to say if the code is
executed by the destructor during stack unwinding.

&rzej

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Bronek Kozicki <brok@spam-trap-cop.net>
Date: Tue, 21 Aug 2007 14:38:14 CST
Raw View
Roman.Perepelitsa@gmail.com wrote:
> Could you explain? Isn't it possible to do something like this?
>
> struct guard: private boost::noncopyable
> {
>     ~guard()
>     {
>         if (std::stack_unwinding())
>             rollback(); // nothrow
>     }
> };

it is possible, except that it will sometimes rollback when it should
commit, eg. when transaction itself is started inside a destructor. More
on this here http://gotw.ca/gotw/047.htm


B.


--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: frege <gottlobfrege@gmail.com>
Date: Wed, 22 Aug 2007 00:50:49 CST
Raw View
On Aug 21, 10:18 am, Greg Herlihy <gre...@pacbell.net> wrote:
> On Aug 19, 11:55 pm, restor <akrze...@interia.pl> wrote:
>
> > The problem here is how to implement the function needRollback that
> > would tell as if the piece of code executing now is caused directly by
> > stack unwinding as opposed to regular stack operation.
> > Function std::uncaught_exception isn't necessarily a good choice as it
> > desn't give us the answer we want in the nested try blocks entered
> > during stack unwinding.
>
> I'm not clear on that last point: What is the answer that you want
> uncaught_exception() to give within the nested try blocks - and why do
> you want that particular answer?
>
> Greg
>


I think this is in reference to Guru of the Week #47 and 66 (http://
gotw.ca/gotw/047.htm and http://gotw.ca/gotw/066.htm).
The articles could definitely help the discussion either way.

P.S.  I've also come across a couple of places where I'd like to know
whether throwing would lead to terminate.  I understand Sutter's
reasoning for why this is typically "Immoral", but there are always
strange examples where it would be useful.

Tony

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]