empty throw ^ missing throw before c++11

[[Josuttis]] P25 is concise on this topic, and explains why noexcept is superior.

Background – all exception specs beside these 2 are deprecated in c++11. Only these 2 forms proved useful. Let’s rephrase the question as “Real difference between 2 otherwise identical functions, one with empty throw() the other without throw”.

Short Answer — wrapping the empty-throw function call in try/catch is useless.

Short answer – empty throw means “should throw Nothing. Nothing expected“;
Short answer – missing throw means the opposite — “all exceptions expected

Long answer — suppose you wrap each function call in a try/catch (…) ie catch-all. For the function without throw, every single exception from it will fall into your catch(…). For the empty-throw function, every single exception always, always triggers unexpected(). Your try/catch is ignored by compiler — could be removed during compilation.

Now we are ready to look at a function with throw(A). According the ARM, if at runtime this function throws unlisted exceptions, it’s seen as a serious design fault, so serious that compiler will *disregard* your try/catch — paper over (huge) cracks.

Here’s a best practice from http://www.gotw.ca/publications/mill22.htm — Moral #1: Never write an exception specification. If you follow this advice, then your try/catch will work, ie won’t be stripped off by compiler

My advice — “Either don’t list the exceptions, or adhere to your list. If you bother to list the expected exceptions, then stick to it. Don’t throw anything else. ”

Note unexpected() is called always, always due to an explicit exception-spec i.e. an explicit throw suffix. “Unexpected” means “function author informed compiler to *expect* some exceptions, but something unexpected came out from the function“.

Let’s repeat the message — whenever you notice unexpected() invoked, there’s a function with a broken exception spec — No smoke without fire. No throw suffix then no “unexpected()”.

Further, these 2 conditions always lead to each other —

function has an exception list, but unlisted exceptions generated unexpected() invocation

What about terminate()? It’s somewhat peripheral in the story of exception-spec. I will just describe one of the causes — an expected (i.e. listed) exception is thrown but not caught. Also, unexpected() calls terminate() by default.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s