tags:

views:

360

answers:

5

std::exception class is defined as follows

exception() throw() { }
virtual ~exception() throw();
virtual const char* what() const throw();

what does the throw() syntax mean in a declaration? Can throw() take parameters? What does no parameters mean?

+7  A: 

Without any parameter, it means that the mentioned functions does not throw any exceptions.

If you specify anything as a parameter, you're saying that the function will throw only exceptions of that type. Notice, however, this is not an enforcement to the compiler. If an exception of some other type happens to be thrown the program will call std::terminate().

ltcmelo
Note that not all compilers support this syntax. Of particular note, VS2008 doesn't.
John Dibling
Really??? It's not a particularly new feature.
anon
That's the default unexpected exception handler. A user may decide to change it using std::set_unexpected(). However, that typically doesn't buy a user very much. Herb Sutter has a great GoTW article on this topic: http://www.gotw.ca/gotw/082.htm
Void
@Neil: I believe VC++ recognizes exception specifications but it does not enforce them, unless things have changed recently.
Void
When using such specifications in VS 2008, its IntelliSense stopped working in that particular function for me :(
smerlin
@Neil:VC++ supports the *syntax*, but does not enforce the semantics. It does, however, recognize an empty exception specification, and performs a few optimizations based on their presence. Anything with an empty exception specification that throws an exception basically causes undefined behavior.
Jerry Coffin
+1  A: 

It's an exception specification. No arguments means that the function can't throw any exceptions.

Autopulated
+10  A: 

It's an "exception specification". throw() means "this function will not throw any exceptions". You can also specify exceptions, so throw(foo) would say this function may throw exceptions of type foo.

The usefulness of this feature has been debated quite a bit in the C++ community - the general evaluation seems to be that it is not particularly useful. For more details take a look at this Herb Sutter article.

anon
Thanks for the link to that article.
Murali
I sort of object to the alleged meaning "this function will not throw any exceptions". What it really means is more like "calls to this function will catch any exceptions it throws, and terminate". If people thought of it that way, it wouldn't take Herb Sutter to persuade them that it's not very useful. And they especially wouldn't think that empty throw specifications are an optimisation.
Steve Jessop
@Steve Well, most people _really_ don't want to have terminate() called, so I think they make an effort to make it mean what I said. As for optimisations, I've never come across that idea before.
anon
@Neil: Yes, a few compilers (notably, VC++, which otherwise ignores them) optimize based on the presence of an empty exception specification. I've yet to meet anybody who could show a good use for a non-empty specification, but empty ones can be of some use -- in particular, most exception safety is impossible without at least a few primitives that are guaranteed not to result in any exceptions (e.g. implementing assignment via copy and swap requires that swap never throws).
Jerry Coffin
@Jerry: nothrow functions are useful, but decorating them with empty throw specifications is much less so. IIRC, that VC++ optimization was actually wrong. It did the thing people think an empty throw specification should do (assume the function won't throw), instead of the thing it actually means (surround the call with a try/catch/terminate).
Steve Jessop
@Steve: at least during development, it can be extremely handy to know that something you thought shouldn't throw, actually did. It's much better to have it fail quickly and noisily than slowly and silently, usually with the problems compounded. It is, however, often handy to use set_new_handler to use a function that at least attempts to tell you want it can about what went wrong.
Jerry Coffin
Fair point, but it depends how much you catch exceptions - if you pretty much never catch them, then your program pretty much fails quickly and noisily regardless of exception specifiers. I guess that with a macro that's defined to `throw()` in debug builds and empty in non-debug, your plan would give the benefits without the costs.
Steve Jessop
+1  A: 

This is called a throw specification. It defines which exceptions (if any) can be thrown from the function.

These sound great in theory, but there are issues with using them.

A good discussion about this can be found at this SO question.

RC
A: 

Can throw() take parameters?

Yes it can be used to declare what parameteres the method is allowed to throw.

Also the destructor is marked as throw(), destructors should never ever throw exceptions as they may already be executing in the context of a thrown exception.

martsbradley
To clarify, the destructor as declared is correct: throw() indicates that the destructor will NOT throw an exception, which is the appropriate pattern.
Dathan