0

Why can you specify a type of the parameter for the throw keyword when you can throw another type anyway? An example:

class A {};
class B {};

void tryexcept() throw(B*)
{
    B* b = new B();
    A* a = new A();
    throw (a); // It works pretty smooth?
}
Int main()
{
try {
        tryexcept();
    }
    catch (A* style)
    {
        cout << "in handler for A\n";

    }
    catch (B* style)
    {
        cout << "in handler for B\n";

    }
    catch (...)
    {
        cout << "in handler for everything\n";

    }
return 0;
}

Output:

in handler for A

Btw. I am using Visual Studio.

But in the function declaration, I set the parameter type of throw to B*, so how can I throw an object of type A*? I mean it works just as if I had declared the function like void tryexcept() throw(A*) since the right catch block is being used.

  • Possibly related: [Should I use an exception specifier in C++?](https://stackoverflow.com/questions/88573/should-i-use-an-exception-specifier-in-c) – Rakete1111 Jun 11 '17 at 14:53
  • 3
    The compiler you use doesn't appear to implement exception specifications correctly. The [correct outcome](http://rextester.com/PDNTIK21450) is a call to `unexpected()`, and ultimately `terminate()` – Igor Tandetnik Jun 11 '17 at 14:55
  • I think @IgorTandetnik is right; what compiler was used here? – paisanco Jun 11 '17 at 15:01
  • 3
    Note also that dynamic exception specifications (of which `throw(B*)` is one) are deprecated as of C++11. It's unwise to use them in new code. – Igor Tandetnik Jun 11 '17 at 15:01
  • @IgorTandetnik, I know. And okay but shouldn't Visual Studio have a compiler that works as expected? –  Jun 11 '17 at 15:04
  • Like to call unexpected() and maybe give a warning? –  Jun 11 '17 at 15:04
  • Protip: never expect anything from MSVC. – Quentin Jun 11 '17 at 15:20

1 Answers1

1

According to Microsoft's own documentation see here and here, Visual Studio departs from the C++ standard in how it treats dynamic exception specifications.

It treats this case as if you wrote void tryexcept() throw(). std::unexpected does not get called in this case if using Visual Studio. The Microsoft documentation warns that the program may not run correctly if an exception is thrown from the function, the expectation is that one won't be. It appears to have "worked" in this case.

The C++ standard behavior should be that std::unexpected is called if an attempt is made to throw an exception of a type not specified, and in turn std::unexpected should call terminate().

And this feature is deprecated in C++11 and onward.

paisanco
  • 4,098
  • 6
  • 27
  • 33
  • To be perfectly clear, the departure from the C++ standard is only in how MSVC handles `throw()`. VS 2015 and later support the C++11 standard's `noexcept`, and [are supposed to do it in a standards-compliant way](https://msdn.microsoft.com/en-us/library/dn956976.aspx): *"If an exception does reach a function marked noexcept, std::terminate is invoked immediately and there is no guarantee that destructors of any in-scope objects will be invoked."* It goes without saying that `noexcept` is what you should be using. The old-style exception specifications were close to useless and now deprecated. – Cody Gray - on strike Jun 11 '17 at 15:59