0

I understand that writing exception-safe code basically means taking into account what part of the code can throw exception, so that you can offer some guarantee about the behavior when an exception is indeed thrown. In particular, I take it that the best is to write code with a nothrow guarantee if the situation permits it.

The thing is, how do I know that my code cannot throw?

More precisely:

  • Let's say that all functions that I use cannot throw (they have the noexcept(true) specifier, which I check with static_assert, and are implemented to ensure it).
  • Knowing that, can something still throw, like operations on basic types or function calls throw (not the function itself, but the function call)?
  • Can an error occur without leading to an exception (for example, I heard that dividing an int by zero results in an error, but does not throw)
Eternal
  • 2,648
  • 2
  • 15
  • 21
  • 2
    Divide by 0, buffer overrun, OS security, numeric overflow, etc., etc. "how can I know that my code won't ever throw any exception?" - you can't - best you can do is decide what to do if it _does_ throw an exception. – D Stanley Jun 26 '14 at 15:20
  • 2
    Basically anything in the standard that says it is gonna throw an exception, plus any use of the keyword throw :) – Drax Jun 26 '14 at 15:22
  • @Drax: Plus any occurence of UB, naturally. – Deduplicator Jun 26 '14 at 15:25
  • @Deduplicator good luck relying on that :) – Drax Jun 26 '14 at 15:29
  • 1
    @Drax: Of course I rely on it being allowed to throw exceptions, I just don't rely on it doing so. ;-) – Deduplicator Jun 26 '14 at 15:30
  • As explained at http://exceptionsafecode.com , the only way to write exception safe code is by assuming that any function call (bar the destructor) will throw. Even if it says noexcept or trow(), that might be removed later and your code will break. This does not mean you should put try-catch around _every call_, you just need to catch exceptions at places where you can actually do something with it, and all your code should properly clean up memory in exception cases (also see RAII). I suggest you watch the 2-parter video in that link, it explains what I said here in more detail. – Aberrant Jun 26 '14 at 15:33
  • @Eternal - If your own code doesn't use the keyword `throw`, and you call functions that are *documented* not to throw, then assume no exception is thrown. If an exception *is* thrown after you have determined that your code doesn't `throw`, and the function(s) you're calling did not document that they `throw`, then consider that a "bug" -- not a true programming bug, but a "bug" in the documentation of that function that threw the exception. – PaulMcKenzie Jun 26 '14 at 15:54
  • @Aberrant: `noexcept` is very clearly meant to document functions that cannot throw. Exception-safe code *requires* that a small subset of operations be non-throwing, RAII can only take you so far. For example, move operations, swap operations and destructors that are marked as `noexcept` can safely be assumed to in fact not throw (and if you really want to be safe, `static_assert(noexcept(whatever), "'whatever' must be noexcept")`). – Mankarse Jul 01 '14 at 01:59
  • @Mankarse Destructors should indeed never throw, because you can't catch those exceptions. `std::swap` is declared `noexcept` by the standard, so currently won't throw. But perhaps a future standard will remove the `noexcept` keyword and your exception safety will be gone. [It's incorrect to say move constructors can be assumed to not throw](http://stackoverflow.com/questions/4732084/c-move-semantics-and-exceptions?lq=1). Mainly because default move constructors will resort to copying members when they cannot be moved. – Aberrant Jul 01 '14 at 05:51
  • @Aberrant: Read my comment again, in particular "that are marked as `noexcept`". – Mankarse Jul 01 '14 at 06:22
  • @Mankarse Read both of my comments again, in particular the parts that mention the `noexcept` might get removed later on. ;) It's simply not safe to assume the code will stay the same. `static_assert` is a good tool when you are forced to have something be `noexcept` (for example, when some third party interface requires it somehow), but it's still not right to say that you can _assume_ those functions are safe. Or, better said, it's not safe to assume they _stay_ safe. The word assume is the problem. – Aberrant Jul 01 '14 at 06:46
  • @Aberrant a future standard might allow destructors to throw safely. – n. m. could be an AI Jul 01 '14 at 16:57

0 Answers0