C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

use of std::uncaught_exception()

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
John Torjo
Guest





PostPosted: Wed Oct 27, 2004 1:04 am    Post subject: use of std::uncaught_exception() Reply with quote



Hi all,

I'd like to know if you've used/relied of correct behavior of
std::uncaught_exception in your code - that is in destructors (code
shown below).

Of course, simple examples always work (not of VC6, on other
compilers:))

Thus, I'd like to ask you if you've used/relied on
std::uncaught_exception() in commercial code (or put in another way,
non-toy programs).

Thanks.

#include <iostream>
struct test {
test() { std::cout << "test" << std::endl; }
void do_throw() { throw 1; }
~test() {
std::cout << "~test" << std::endl;
if ( !std::uncaught_exception() )
throw 2;
}
};

int main() {
try {
test o;
o.do_throw();
}
catch( int & i) {
std::cout << "i= " << i << std::endl;
}
return 0;
}

// expected output:
// test
// ~test
// i= 1

In particular, I want to know if I can throw an exception from a
destructor in a way similar to shown above - and to know if modern
compilers can take it.

(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Bob Hairgrove
Guest





PostPosted: Wed Oct 27, 2004 1:59 pm    Post subject: Re: use of std::uncaught_exception() Reply with quote



On 26 Oct 2004 21:04:54 -0400, [email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote:

[snip]
Quote:
(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

Destructors which throw are evil. Read Scott Meyer's "More Effective
C++", Item 11 (publ. by Addison-Wesley, ISBN 0-201-63371-X) titled:
"Prevent exceptions from leaving destructors".

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Jonathan Turkanis
Guest





PostPosted: Thu Oct 28, 2004 2:06 pm    Post subject: Re: use of std::uncaught_exception() Reply with quote




"John Torjo" <jtorjo (AT) yahoo (DOT) com> wrote

Quote:
Hi all,

I'd like to know if you've used/relied of correct behavior of
std::uncaught_exception in your code - that is in destructors (code
shown below).

<snip>

Quote:
In particular, I want to know if I can throw an exception from a
destructor in a way similar to shown above - and to know if modern
compilers can take it.

(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

More to the point than item 11 in More Effictive C++ is item 19 in More
Exceptional C++. Herb refers to your code (which I snipped) as the
'wrong
solution.' Here are the relevant bits:

"Why the Wrong Solution is Unsound: The first problem is that the idiom
....
won't actually work as intended.... because it can end up using the
path that
doesn't throw even when it would be safe to throw [because the
exception would
be caught higher up]."

"Why the Wrong Solution Is Immoral: ... it is always poor design to
allow an
operation to report the same error in two different ways....It
complicates the
interface and the semantics. And it makes the caller's life harder
because the
caller must be able to handle both flavors of error reporting."

Of course, that doesn't answer the question whether the wrong solution
has been
used successfully in commercial code ;-)

Quote:
Best,
John

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Peter Koch Larsen
Guest





PostPosted: Thu Oct 28, 2004 2:14 pm    Post subject: Re: use of std::uncaught_exception() Reply with quote


"John Torjo" <jtorjo (AT) yahoo (DOT) com> skrev i en meddelelse
news:c638aac5.0410260717.1346a222 (AT) posting (DOT) google.com...
Quote:
Hi all,

I'd like to know if you've used/relied of correct behavior of
std::uncaught_exception in your code - that is in destructors (code
shown below).

std::uncaught_exception asks whether there is an uncaught exception,
and I'm
not sure that is the question you want to have answered. Most of the
time,
the interesting question is whether your exception will call terminate.
You
can not use uncaught_exception for that.
Apart from that your question is rather platform-specific, and as I have
never used that feature, i can't give you an answer.

[snip]

Quote:
In particular, I want to know if I can throw an exception from a
destructor in a way similar to shown above - and to know if modern
compilers can take it.

(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

My best advice is: don't throw. I am aware that there are occasions
(such as
closing of files) that could cause an error which it would be nice to
tell
about via an exception. In that case you could perhaps use an
alternative
function ("close"), that could throw. That principle is the best i can
think
of.

Kind regards
Peter
Quote:

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
^^^^^^^^^^^^^^^^^^ this library is just way cool, John.


[snip}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Alberto Barbati
Guest





PostPosted: Fri Oct 29, 2004 1:44 am    Post subject: Re: use of std::uncaught_exception() Reply with quote

Bob Hairgrove wrote:
Quote:
On 26 Oct 2004 21:04:54 -0400, [email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote:

[snip]
(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

Destructors which throw are evil. Read Scott Meyer's "More Effective
C++", Item 11 (publ. by Addison-Wesley, ISBN 0-201-63371-X) titled:
"Prevent exceptions from leaving destructors".


Please notice that that article had been written before
uncaught_exception() was introduced into the C++ standard (at least
that's what footnote 4 in my edition suggests).

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Alberto Barbati
Guest





PostPosted: Fri Oct 29, 2004 1:46 am    Post subject: Re: use of std::uncaught_exception() Reply with quote

John Torjo wrote:
Quote:
Thus, I'd like to ask you if you've used/relied on
std::uncaught_exception() in commercial code (or put in another way,
non-toy programs).

The most notable use of std::uncaught_exception() is in the C++ standard
library itself! Specifically it's in the destructor of
basic_ostream::sentry (27.6.2.3/4): "If ((os.flags() &
ios_base::unitbuf) && !uncaught_exception()) is true, calls os.flush()."

That's because os.flush() may throw, so the check is necessary to avoid
the library call terminate() accidentally.

Quote:
In particular, I want to know if I can throw an exception from a
destructor in a way similar to shown above - and to know if modern
compilers can take it.

You are allowed to throw from destructors and it's better to check
uncaught_exception() before doing that. Whether throwing from
destructors is good or bad coding style, I'm not going to tell you as I
am pretty sure a flame war will soon start on such subject ;-)

I tried gcc 3.3.3 and VC++ 7.1 and both of them correctly implement
uncaught_exception(). IIRC older versions of VC++ had problems with that.

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Torjo
Guest





PostPosted: Fri Oct 29, 2004 2:15 am    Post subject: Re: use of std::uncaught_exception() Reply with quote

Bob Hairgrove <invalid (AT) bigfoot (DOT) com> wrote

Quote:
On 26 Oct 2004 21:04:54 -0400, [email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote:

[snip]
(There is a possibility that my destructor could throw. I want to
throw an exception only if there's no exception thrown yet)

Destructors which throw are evil. Read Scott Meyer's "More Effective
C++", Item 11 (publ. by Addison-Wesley, ISBN 0-201-63371-X) titled:
"Prevent exceptions from leaving destructors".

Yes, I'm aware of that. Still, I want my original question to be answered ;)

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bob Bell
Guest





PostPosted: Fri Oct 29, 2004 2:14 pm    Post subject: Re: use of std::uncaught_exception() Reply with quote

[email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote in message news:<c638aac5.0410260717.1346a222 (AT) posting (DOT) google.com>...
Quote:
Hi all,

I'd like to know if you've used/relied of correct behavior of
std::uncaught_exception in your code - that is in destructors (code
shown below).

Of course, simple examples always work (not of VC6, on other
compilers:))

Thus, I'd like to ask you if you've used/relied on
std::uncaught_exception() in commercial code (or put in another way,
non-toy programs).

Some compilers can take it, some can't. But I don't ever write code
this way. Others have given some good reasons why not. Here are a
couple of others.

If you've got to handle the problem somehow when you think you can't
throw, why not handle it the same way even when you think you can
throw? Wouldn't that be simpler for everyone?

No one expects destructors to throw. For example:

// Use "two-step" strong exception safety:
void F()
{
// Step one: operations that might throw:
A a;

// ...

// Step two: operations that don't throw:

// ...

}

a.~A() is called in the non-throwing step; it would be quite
surprising to have an exception thrown here, after the state of the
system was updated.

If you've got some kind of cleanup operation in your class that must
be able to throw, make it an ordinary member function and require your
clients to call it. If you really need to, you can add a flag to your
class that tracks whether this cleanup function is called, so the
destructor can assert() if an object is destroyed without having that
function called. Yes, this is ugly, and yes, it's much better than a
throwing destructor.

Bob

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hubert Schmid
Guest





PostPosted: Fri Oct 29, 2004 2:36 pm    Post subject: Re: use of std::uncaught_exception() Reply with quote

Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> writes:

Quote:
I tried gcc 3.3.3 and VC++ 7.1 and both of them correctly implement
uncaught_exception().

std::uncaught_exception() was broken (unusable) in GCC3 a long time.
It is still broken in gcc 3.3.5 and it has been fixed in gcc 3.4.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14026

regards, Hubert

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Torjo
Guest





PostPosted: Sun Oct 31, 2004 11:00 am    Post subject: check_invariant (was Re: use of std::uncaught_exception()) Reply with quote

[email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote in message
news:<c638aac5.0410260717.1346a222 (AT) posting (DOT) google.com>...
Quote:
Hi all,

I'd like to know if you've used/relied of correct behavior of
std::uncaught_exception in your code - that is in destructors (code
shown below).
[...]

Thanks for your answers. Here's what I want to do. I want to have a
check_invariant class, which checks that an invariant is true when
entering a function, and when exiting it.
That is :
void some_class::f() {
check_invariant chk(this, &some_class::is_valid);
... // code
}

The invariant, in case it does not hold, it can choose to throw an
exception. I don't want a debate whether that's a good thing or not -
I just want to know if this works.

Here's the code for it:

// this is version 1.0 - anyway, I'm interested in
// whether the destructor works as expected
struct check_invariant : private boost::noncopyable {
template<class type> check_invariant(type * self, void
(type::*func)() const)
: checker( boost::bind( boost::mem_fn(func), self)) {
checker(); }
check_invariant( void (*func)() ) : checker(func) { checker(); }
~check_invariant() {
bool any_exc = std::uncaught_exception();
try {
checker();
} catch(...) {
if ( !any_exc) throw;
}
}
private:
boost::function<void()> checker;
};

The idea is:
The invariant will be checked when exiting the function, even if the
function is exited by an exception.

If it's exited by an exception, it lets that exception propage.

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
J Lindrud
Guest





PostPosted: Sun Oct 31, 2004 11:04 am    Post subject: Re: use of std::uncaught_exception() Reply with quote

[email]jtorjo (AT) yahoo (DOT) com[/email] (John Torjo) wrote in message
news:<c638aac5.0410272346.8843a41 (AT) posting (DOT) google.com>...
Quote:
Bob Hairgrove <invalid (AT) bigfoot (DOT) com> wrote in message
[snip]
Destructors which throw are evil. Read Scott Meyer's "More Effective
[snip]

Yes, I'm aware of that. Still, I want my original question to be answered ;)

Best,
John


I sure don't want to come across as evil... but FWIW here's a scenario
I've come across.

I have a macro called THROW, which is used like this:

void func(int x, int y)
{
// ...
THROW( std::runtime_error, "Something went wrong")(x)(y);
}

The result is the throwing of a std::runtime_error, with the given
message, along with the variable names and values of the appended
arguments, in this case x and y. So the exception message look like
this: "Something went wrong: x=1, y=2," .

The macro is implemented by constructing a temporary variable at the
macro invocation site, and the actual throw statement is located in
the destructor of the temporary variable. There's no way of getting
around that, since I want the user to be able to append any number of
expressions to the macro invocation, without requiring a special final
function call to invoke the throw.

The problem is that when an expression is appended to the macro
invocation (the (x) or (y) in the example), it could trigger an
exception while writing to a std::ostringstream etc, and then we
certainly don't want to throw again while destroying the temporary,
since that would terminate the program.

Calling std::uncaught_exception() in the temporary's destructor comes
in very useful to keep that from happening.

std::uncaught_exception() doesn't give a precise answer to the
question "is it safe to throw now?" (sometimes it's safe to throw
regardless of what std::uncaught_exception() tells you), but if it
returns false, at least you're guaranteed that a throw won't terminate
the program.

/Jarl

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.