4

After watching many videos, reading a book, I am unclear about when and when not to use noexcept.

All of the books say that you should only use noexcept when a function WILL NEVER EVER throw.

I think it should be used otherwise. Many say that functions that allocate shouldn't be noexcept, but what if I don't want to catch those errors, and a call to std::terminate is acceptable?

In short, should noexcept be used on functions that will never throw, or on all functions except the ones you would like to catch exceptions from.

IMHO some exceptions don't need to be caught (ie out of memory etc)

Russell Greene
  • 2,141
  • 17
  • 29
  • `some exceptions don't need to be caught (ie out of memory etc)` Seriously? – deviantfan Jul 15 '15 at 04:02
  • 3
    Yes, a call to std::terminate is fine for me. How does one recover from that? – Russell Greene Jul 15 '15 at 04:03
  • 1
    And no, don´t make a throwing function noexcept. If you don´t want to catch it, you can do it like you want, even without noexcept. – deviantfan Jul 15 '15 at 04:03
  • 1
    `How does one recover from that?` Eg. writing some log, closing files, telling the user if he want to terminate or retry, etc.etc. Depends on what the program is doing. – deviantfan Jul 15 '15 at 04:05
  • 1
    To follow up with what @deviantfan is getting at. If you want to terminate your program, terminate your program. Don't rely on your abuse of a keyword to do it for you. If you make a habit of doing things like that, it will kick you in the ass one day. – Taekahn Jul 15 '15 at 07:01
  • I don't see your "otherwise" as any different. If you create an allocation function that either returns successfully, or terminates the program, then that "function WILL NEVER EVER throw". –  Jul 15 '15 at 07:10

1 Answers1

3

The marker noexcept is a gurantee from the developer to the compiler that the function will never throw.

So you should add it to functions that you know Should never throw. If these functions do for some obscure and unknowable reason throw the only thing the compiler can do is terminate the application (as you guaranteed something that should not happen). Note: from a function marked noexcept you should probably not call another function unless it is also marked noexcept (just like const correctness you need to have noexcept correctness)

Where you should use it:

  swap()   methods/functions. 
           Swap is supposed to be exception safe.
           Lots of code works on this assumption.

  Move Constructor
  Move Assignment.
           The object you are moving from should already be
           fully formed so moving it is usually a processes of
           swapping things around.

           Also be marking them noexcept there are certain 
           optimizations in the standard library that can be used.

     Note: This is usually the case.
           If you can not guarantee that move/swap semantics are 
           exception safe then do not mark the functions as noexcept.

You don't want to call terminate on all exceptions. Most of the time I would allow the exception to unwind the stack calling destructors and releasing resources correctly.

It it is not caught then the application will terminate.

But most complex applications should be resilient to exceptions. Catch discard the initiated task log the exception and wait for the next command. Sometimes you still want to exit but just because my smudge operation in the graphics application fails does not mean I want the application to exit ungracefully. I would rather that the smudge operation is abandoned resource re-claimed and the application goes back to normal operations (so I can save exit and restart).

Martin York
  • 257,169
  • 86
  • 333
  • 562