8

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?

Murali
  • 1,495
  • 2
  • 15
  • 28

5 Answers5

18

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.

  • Thanks for the link to that article. – Murali Jan 13 '10 at 18:00
  • 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 Jan 13 '10 at 19:32
  • @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. –  Jan 13 '10 at 19:34
  • @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 Jan 13 '10 at 22:06
  • @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 Jan 13 '10 at 22:10
  • @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 Jan 14 '10 at 18:43
  • 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 Jan 15 '10 at 01:38
12

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().

Robert Deml
  • 12,390
  • 20
  • 65
  • 92
Leandro T. C. Melo
  • 3,974
  • 22
  • 22
  • Note that not all compilers support this syntax. Of particular note, VS2008 doesn't. – John Dibling Jan 13 '10 at 17:57
  • 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 - Othman Jan 13 '10 at 18:01
  • 4
    @Neil: I believe VC++ recognizes exception specifications but it does not enforce them, unless things have changed recently. – Void - Othman Jan 13 '10 at 18:03
  • When using such specifications in VS 2008, its IntelliSense stopped working in that particular function for me :( – smerlin Jan 13 '10 at 20:24
  • @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 Jan 13 '10 at 22:01
1

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

James
  • 24,676
  • 13
  • 84
  • 130
1

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.

Community
  • 1
  • 1
RC.
  • 27,409
  • 9
  • 73
  • 93
0

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.

avakar
  • 32,009
  • 9
  • 68
  • 103
martsbradley
  • 148
  • 1
  • 9
  • 1
    To clarify, the destructor as declared is correct: throw() indicates that the destructor will NOT throw an exception, which is the appropriate pattern. – Dathan Jan 13 '10 at 18:12