views:

2065

answers:

4

i am reading this page http://www.cplusplus.com/doc/tutorial/exceptions.html it says if i write function() throw(); no exceptions can be thrown in that function. I tried in msvc 2005 writing throw(), throw(int), throw() and nothing at all. each had the exact same results. Nothing. I threw int, char*, another type and it was all caught the same way. It looks like throw doesnt affect it at all. What does function() throw() actually do?

+7  A: 

See this article for details on C++ exception specifications and Microsoft's implementation:

Microsoft Visual C++ 7.1 ignores exception specifications unless they are empty. Empty exception specifications are equivalent to __declspec(nothrow), and they can help the compiler to reduce code size.

[...] If it sees an empty exception specification, it will assume you know what you are doing and optimize away the mechanics for dealing with exceptions. If your function throws anyway - well, shame on you. Use this feature only if you are 100% positive your function does not throw and never will.

Nemanja Trifunovic
That is very different from what the standard says... I guess one more reason not to use them
Greg Rogers
Thanks for editing, Shog ;)
Nemanja Trifunovic
+1  A: 

Throwing an exception is not enough, you need a try {} catch() block to catch exceptions. If you don't catch exceptions, std::terminate() is called and your program exits abruptly. Take some time out and have go at this.

dirkgently
Which isn't what he was asking.
David Thornley
A: 

throw specifications are designed for two purposes:

  1. To serve as a contract between interface implemented and interface user - you state which exceptions can be throwned from your method, some people consider it part of an interface. (contract) Ala checked exceptions in Java.

  2. As a way to signal the compiler that it can apply certain optimizations in case no exceptions can be thrown from a method/procedure (setting up exception handling costs something)

Throwing an exception not specified in throw() clause is a mistake, however at no point is the implementation required to verify it for you. In fact it's not even possible to verify, as it includes all the possible exceptions from subroutines your subroutine calls. (possibly from other modules) It is not even possible within a single module, as is easily reduced to a halting problem :)

EFraim
Completely incorrect for C++. Exception specifications are required to be checked at runtime, and they do not in general allow optimizations.
David Thornley
That's not my point. They are not required to be checked in COMPILE-TIME. They also allow optimization in case of NO EXCEPTIONS (IMHO C++ Language FAQ mentions it). So your vote down is incorrect.
EFraim
+3  A: 

What you're finding is that that version of VC++ didn't enforce specification exceptions. I believe that was documented as a variance from the standard.

However, exception specifications are usually not a good idea. If a program violates them in a standards-conforming implementation (which the VC++ from VS 2005 was not in this case), the system is supposed to catch it. This means that the specification is not a compiler optimization hint, but rather forces the compiler to go to extra lengths, and sometimes produce suboptimal code.

See the Boost rationale for reasons why the highly regarded Boost project does not use exception specifications. This is Boost, which is something of the poster child for doing weird and useful things with advanced parts of the language.

David Thornley