Thread: Why does C++ need throw()

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    Why does C++ need throw()

    I understand that An exception specification with an empty throw, as in

    void MyFunction(int i) throw();

    tells the compiler that the function does not throw any exceptions. But why do we need this function? If MyFunction doesn't want to throw() something, then just doesn't throw it.

    What happens when MyFunction() throw() actually throws an exception?

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> If MyFunction doesn't want to throw() something, then just doesn't throw it.
    Because the throw() guarantees that it won't throw an exception. This is an important part of design for several reasons. For example, if you are doing processing in your code and you call a function part way through, if that function might throw an exception then you should be able to handle that and either undo the processing you've already done or make sure you leave your data in a valid state. If you call a function that guarantees it won't throw an exception, then you don't have to worry about it because it won't happen.

    >> What happens when MyFunction() throw() actually throws an exception?
    Bad things. I think maybe the program aborts, but I don't remember exactly.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Daved View Post
    >> What happens when MyFunction() throw() actually throws an exception?
    Bad things. I think maybe the program aborts, but I don't remember exactly.
    As a matter of fact, unexpected() is called. unexpected() will call terminate() [or throw another exception which is within the function's exception specification, but with a throw() specification that is a moot point]. By default (if the program has not installed a terminate_handler) terminate() will invoke abort(). abort() terminates the program without executing destructors of any local or global objects, and without calling any exit handlers that the program may have passed to atexit().

    Net effect is usually that the program terminates with prejudice, with no cleanup.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It serves as a promise by the programmer that the function won't throw any exception. It's part of the declaration, so someone using the function does not have to look inside the function itself to figure out which exceptions it can throw.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Daved View Post
    >> If MyFunction doesn't want to throw() something, then just doesn't throw it.
    Because the throw() guarantees that it won't throw an exception. This is an important part of design for several reasons. For example, if you are doing processing in your code and you call a function part way through, if that function might throw an exception then you should be able to handle that and either undo the processing you've already done or make sure you leave your data in a valid state. If you call a function that guarantees it won't throw an exception, then you don't have to worry about it because it won't happen.

    >> What happens when MyFunction() throw() actually throws an exception?
    Bad things. I think maybe the program aborts, but I don't remember exactly.
    Don't use exception specifications. They have no real benefit.
    http://www.ubookcase.com/book/Addiso...5lev1sec2.html
    Quote Originally Posted by Herb_Sutter
    A common but nevertheless incorrect belief is that exception specifications statically guarantee that functions will throw only listed exceptions (possibly none), and enable compiler optimizations based on that knowledge.

    In fact, exception specifications actually do something slightly but fundamentally different: They cause the compiler to inject additional run-time overhead in the form of implicit try/catch blocks around the function body to enforce via run-time checking that the function does in fact emit only listed exceptions (possibly none), unless the compiler can statically prove that the exception specification can never be violated in which case it is free to optimize the checking away. And exception specifications can both enable and prevent further compiler optimizations (besides the inherent overhead already described); for example, some compilers refuse to inline functions that have exception specifications.

    Worst of all, however, is that exception specifications are a blunt instrument: When violated, by default they immediately terminate your program. You can register an unexpected_handler, but it's highly unlikely to help you much because you get exactly one global handler and the only way the handler could avoid immediately calling terminate would be to rethrow an exception that is permissiblebut because you have only one handler for your whole application, it's hard to see how it could do useful recovery or usefully know what exceptions might be legal without trivializing exception specifications altogether (e.g., following the discipline of having all exception specifications allow some general UnknownException eliminates any advantage that having an exception specification might have had in the first place).

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cpjust View Post
    Don't use exception specifications. They have no real benefit.
    That used to be true, but as of Orcas using the no throw specification can in some cases result in more optimised code, according to the Microsoft video on C++ exception handling I watched recently.

    There's always the documentation bennefit too, as it shows up in intellisense and can tell you that there's no point putting a try block around the call..
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Code:
    #if defined(NOTHROW_HELPS)
    #define NOTHROW throw()
    #else
    #define NOTHROW
    #endif
    
    void foo() NOTHROW;
    Now you just need to figure out on which compilers you should define NOTHROW_HELPS. But now you get the documentation no matter what, and the benefits too.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I don't know anything about Orcas, but what if your throw() function calls older functions that have no exception specification and they do throw an exception?
    As I understand it, terminate() will then be called and your program ends.

    I think exception specifications might have worked well if they were implemented in every standard function right from the beginning; but then what about C functions (I know they don't technically throw exceptions, but you can still catch (...) around them to stop a crash from a NULL pointer...)

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    but you can still catch (...) around them to stop a crash from a NULL pointer...)
    No, you can't. Just because it worked in VC++6 doesn't mean it works anywhere else or is a good idea.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I hate exception specifications. They lead you to believe that only certain types of exceptions can be thrown. But what it actually means is that if you throw any other kind of exception, you crash.

    If your function doesn't throw exceptions, just say so in the documentation. The standard library doesn't use exception specifications, neither does Boost, and neither should anyone else in my opinion.

  11. #11
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by brewbuck View Post
    If your function doesn't throw exceptions, just say so in the documentation. The standard library doesn't use exception specifications, neither does Boost, and neither should anyone else in my opinion.
    Boost does as mush as it can. STL doesn't because it relies heavily on templates, and you cannot deduce what exceptions can be thrown by any operation on a template types.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by King Mir View Post
    STL doesn't because it relies heavily on templates, and you cannot deduce what exceptions can be thrown by any operation on a template types.
    Not true. The STL is designed with defined levels of exception safety in the presence of any exception: for example, if an operation on an element of a container throws an exception, then the container remains in a sensible state (it can be destroyed safely, does not generate memory leaks, etc) and the exception propagates to the caller. There are a few conditions on this (eg destructors of container elements are not allowed to throw exceptions, elements of containers must also keep themselves in a destructible state if an exception is thrown, etc). The net effect is that the STL behaves in a rational manner if any exception is thrown, and does not need to know anything about exceptions which might be thrown.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    But in the context of exception specifications it would need to know about which exceptions might be thrown, which is what the thread was talking about.

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by King Mir View Post
    Boost does as mush as it can. STL doesn't because it relies heavily on templates, and you cannot deduce what exceptions can be thrown by any operation on a template types.
    Actually, there are several places in the STL that use exception specifications.

    As for Boost, this is what they have to say about Exception Specifications:

    Quote Originally Posted by Boost
    Exception-specification rationale
    Exception specifications [ISO 15.4] are sometimes coded to indicate what exceptions may be thrown, or because the programmer hopes they will improved performance. But consider the following member from a smart pointer:

    Code:
    T& operator*() const throw()  { return *ptr; }
    This function calls no other functions; it only manipulates fundamental data types like pointers Therefore, no runtime behavior of the exception-specification can ever be invoked. The function is completely exposed to the compiler; indeed it is declared inline Therefore, a smart compiler can easily deduce that the functions are incapable of throwing exceptions, and make the same optimizations it would have made based on the empty exception-specification. A "dumb" compiler, however, may make all kinds of pessimizations.

    For example, some compilers turn off inlining if there is an exception-specification. Some compilers add try/catch blocks. Such pessimizations can be a performance disaster which makes the code unusable in practical applications.

    Although initially appealing, an exception-specification tends to have consequences that require very careful thought to understand. The biggest problem with exception-specifications is that programmers use them as though they have the effect the programmer would like, instead of the effect they actually have.

    A non-inline function is the one place a "throws nothing" exception-specification may have some benefit with some compilers.
    Not a very glowing recommendation in my opinion.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by grumpy View Post
    Not true. The STL is designed with defined levels of exception safety in the presence of any exception: for example, if an operation on an element of a container throws an exception, then the container remains in a sensible state (it can be destroyed safely, does not generate memory leaks, etc) and the exception propagates to the caller. There are a few conditions on this (eg destructors of container elements are not allowed to throw exceptions, elements of containers must also keep themselves in a destructible state if an exception is thrown, etc). The net effect is that the STL behaves in a rational manner if any exception is thrown, and does not need to know anything about exceptions which might be thrown.
    That's exception safety, not exception specification. You don't need exception specifications -- ever.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. STL sort throw exception?
    By George2 in forum C++ Programming
    Replies: 11
    Last Post: 01-10-2008, 06:34 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Long-lasting objects that throw exceptions
    By drrngrvy in forum C++ Programming
    Replies: 7
    Last Post: 10-05-2006, 04:30 PM
  4. throw in method declarations
    By Davros in forum C++ Programming
    Replies: 1
    Last Post: 07-22-2006, 07:33 AM
  5. Parent/child object design
    By lyx in forum C++ Programming
    Replies: 6
    Last Post: 11-28-2003, 09:46 AM