3

In Exception Safety as created by Abrahams we have the three guarantees: basic, strong and no-throw guarantee. Can i say that if i have a codebase using nothrow for "new" and noexcept for method signatures that i have the no-throw guarantee?

Thanks.

2 Answers2

2

You'll have to avoid (or handle and recover from the potential failures of) the following language constructs:

  • dynamic_cast to a reference type, which will throw std::bad_cast if the conversion fails;
  • typeid applied to the result of dereferencing a potentially null pointer, which will throw std::bad_typeid

And of course you'll have to avoid much of the standard library. In particular, things like containers use allocators that can only signal failure by throwing.

You'll struggle to give a no-throw guarantee across "a codebase" (if, by that, you mean the code for a whole program or library), since there will typically be operations that can be expected to fail; these can have at most a strong guarantee.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • You don't _have_ to avoid any of these constructs, so long as you handle the exceptions before the boundaries of the API functions on which you declare the no-throw guarantee. – CB Bailey Sep 01 '14 at 17:12
  • @CharlesBailey: Indeed, "avoid" is rather strong. If the failure is recoverable, then you can handle it and still give a guarantee. – Mike Seymour Sep 01 '14 at 17:14
  • But Sutter says: "Nothrow Guarantee: The function will not emit an exception under any circumstances." http://www.gotw.ca/gotw/059.htm – Fausto Carvalho Marques Silva Sep 01 '14 at 17:18
  • @FaustoCarvalhoMarquesSilva: Indeed. If you want to provide that guarantee, then you'll need to handle and recover from any potential exceptions within the function. If you can't do that, then you can't offer the guarantee. – Mike Seymour Sep 01 '14 at 17:19
  • -fno-rtti is an option? – Fausto Carvalho Marques Silva Sep 01 '14 at 17:20
  • @FaustoCarvalhoMarquesSilva: That will prevent you from using those constructs at all, if that's what you want. But it's rather heavy-handed: it will also prevent RTTI operations that don't throw; and across the entire program, not just the parts that need a no-throw guarantee. – Mike Seymour Sep 01 '14 at 17:27
2

No, that is not a correct conclusion. The no-throw guarantee doesn't simply mean that you don't throw exceptions, it means that the operation always completes successfully. A code base using an allocator that returns nullptr on failure, and indicates function failures by returning a status code, pretty clearly doesn't match that. Nor does a code base that calls abort() on any detected error. Yet both of those are perfectly possible with new(nothrow) and noexcept functions.