Sreeraj Chundayil
Sreeraj Chundayil

Reputation: 5859

Why is this program not getting aborted when an unexpected exception is thrown?

I was going through C++ FAQ 2nd Edition, FAQ 9.04- What is an exception specification?.

There,it is mentioned that if we throw an unexpected exception from a function whose signature specifies a set of predefined exception types, it is supposed to call unexpected()->terminate()->abort(). But my program catches the unexpected exception and is not abort()ing it, why?

#include<iostream>
using namespace std;

class Type1{};
class Type2{};
class Type3{};

void func() throw(Type1, Type2)
{
    throw Type3();
}

int main()
{
    try{
        func();
    }
    catch (Type1 &obj1)
    {
        cout << "Type1 is caught" << endl;
    }
    catch (Type2 &obj2)
    {
        cout << "Type2 is caught" << endl;
    }
    catch (Type3 &obj3)
    {
        cout << "Type3 is caught" << endl;
    }
}

Here I am getting the output Type3 is caught which should not have occured.

IDE: VS2013

Upvotes: 7

Views: 1351

Answers (3)

Adriano Repetti
Adriano Repetti

Reputation: 67090

From MSDN:

Function exception specifiers other than throw() are parsed but not used. This does not comply with section 15.4 of the ISO C++ specification

Visual C++ is simply not following standard (quote from standard in Mohit's answer).

EDIT: about sub-question "why it doesn't?" I try to summarize from comments what has been said.

  • First of all a commercial compiler has always to face cost/benefit ratio. If to implement a feature will costs (directly or indirectly) more than what it worths (directly or indirectly) then there are good chances it won't be implemented (at least soon). In my opinion this is an important consideration, a small feature may impact compiler complexity and performance (also read one of the many Eric Lippert's C# posts about this topic).
  • To implement a feature may greatly impact on performance (this seems the reason in this case, see Serge's answer).
  • Some specifications are unclear and/or bugged. See also What's the point of nested classes?
  • To change something may break existing code. These breaking changes are always take into serious consideration (especially if they don't break anything at compile-time but at run-time). When this may happen? For example:
    • Compiler introduced a language extensions and later in future standard asserts something different about that.
    • Specifications were unclear or they left a detail as implementation specific.
    • Compiler bugs in specifications implementation are well-estabilished. See for example when Microsoft rewrote C# compiler, Roslyin implementation had to reproduce bugs in old compiler. See also SLaks' blog about breaking changes (they didn't do it for everything).
  • Some features (like in this case) adds little value to your code and before they're commercially implemented (don't forget MSVC++ is updated less often than GCC, for example) they're deprecated then there isn't any need to support them.

Upvotes: 4

Serge Ballesta
Serge Ballesta

Reputation: 148965

As said by Adriano Repetti, MSVC is known to ignore exception specifications. But there are some reasons for that.

This other post from SO explains that exception specification explains that compiler cannot enforce exception control as compile time and must generate code to just control it at runtime. That's why it has poor support from compilers (notably MSVC).

And it cites a very details article from GOTW, the conclusion of which is:

So here’s what seems to be the best advice we as a community have learned as of today:

  • Moral #1: Never write an exception specification.
  • Moral #2: Except possibly an empty one, but if I were you I’d avoid even that.

Upvotes: 6

Mohit Jain
Mohit Jain

Reputation: 30489

From except_spec

If the function throws an exception of the type not listed in its exception specification, the function std::unexpected is called.

So it appears VS2013 is not compliant to this section.

Upvotes: 1

Related Questions