3

I'm reading this book on C++ and there's a code example that should behave differently: it should throw an exception or error (sorry for the poor terminology here) anyway it just shouldn't work or so the book says. (the book is rather new so I think its up to date). But in my case the code executes itself and I get the "Exception caught" message.

The author uses a different compiler (WxDev). (I'm using Visual Studio 2019)

#include<exception>

void generate_char_exception() throw(int)
{
    throw 'x';
}

int main()
{
    try
    {
        generate_char_exception();
    }
    catch (...)
    {
        cout << "Exception caught" << endl;
    }

    return 0;
}

Picture of the code from the book: enter image description here

L. F.
  • 19,445
  • 8
  • 48
  • 82
Hentairino
  • 111
  • 7
  • What is the issue? You throw an exception and catch it. – Michael Chourdakis Aug 05 '19 at 20:06
  • I think you have read the book wrong as the proper thing to have happen is to see *Exception caught* printed to the screen. – NathanOliver Aug 05 '19 at 20:07
  • @NathanOliver the thing is that theres throw(int) next to the generate_char_exception() when im passing char. The solution that author gets after using this code is "terminate called after throwing an instance of 'char', This application has requested the Runtime to terminate it in an unusual way." – Hentairino Aug 05 '19 at 20:11
  • @HinterinoSalterino Are you sure the author has in their code `catch (...)` and not `catch(int)`? `catch(...)` will catch anything that is thrown. – NathanOliver Aug 05 '19 at 20:13
  • 2
    `catch (...)` is the universal catch everything case. If the book really says the program should terminate uncaught, you need a new book. Could you add the relevant text from the book to the question so we can help you understand it (or help you find a new book)? – user4581301 Aug 05 '19 at 20:14
  • @NathanOliver its catch(...), might be a spelling mistake but i hereby swear its just like in the example. Might as well post an imgur picture if you would want to see the code straight on paper. – Hentairino Aug 05 '19 at 20:15
  • Do an internet search on `WxDev` (the compiler used by the author) - it's a little out of date. – Richard Critten Aug 05 '19 at 20:17
  • 1
    If I compile with MSVC I get: " warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)" so it is ignoring the specification. Can you confirm having the same warning? – CuriouslyRecurringThoughts Aug 05 '19 at 20:22
  • @NathanOliver so I added the edit with literal photos of the books text (dont mind the language that the book is written in) – Hentairino Aug 05 '19 at 20:23
  • 1
    Crap. That I wasn't expecting. I can handle English and French. But yes, with a compiler building to an older revision of the C++ Standard, the Author is correct. – user4581301 Aug 05 '19 at 20:23
  • @user4581301 that made me lol severly – Hentairino Aug 05 '19 at 20:24
  • @CuriouslyRecurringThoughts "no issues found" so yeah i dont even get a warning. The thing just compiles and I get "Exception caught" in console. – Hentairino Aug 05 '19 at 20:27
  • Increase the level warning to 3, according to https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4290?view=vs-2019 MSVC does not implement exception specification, am I reading it correctly? – CuriouslyRecurringThoughts Aug 05 '19 at 20:30
  • 1
    @CuriouslyRecurringThoughts if you are, we both are. [Here are some notes from Herb Sutter on the old `throw` specification.](http://www.gotw.ca/publications/mill22.htm) the TL;DR version: Don't use it. – user4581301 Aug 05 '19 at 20:37

1 Answers1

7

For starters, throw() specifications are deprecated, prefer noexcept. I question how updated your book is, regardless, I suggest you take a look at this list of good C++ books: The Definitive C++ Book Guide and List. For a more in-depth look on throw specification and why it is bad, see http://www.gotw.ca/publications/mill22.htm (thanks user4581301)

Now, to the answer:

According to https://en.cppreference.com/w/cpp/language/except_spec

If the function throws an exception of the type not listed in its exception specification, the function std::unexpected is called. The default function calls std::terminate, [...]

So the book seems to be right, and when using g++ you get the expected behavior: https://onlinegdb.com/Sy_7DzUmB

terminate called after throwing an instance of 'char'
Aborted

If you use throw(char) the exception gets caught.

Microsoft Visual Studio 2019 does not implement that kind of exception specification: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4290?view=vs-2019

A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications.

And from: https://learn.microsoft.com/en-us/cpp/cpp/exception-specifications-throw-cpp?view=vs-2019

throw(type): (C++14 and earlier) The function can throw an exception of type type. The compiler accepts the syntax, but interprets it as noexcept(false) [...]

Interestingly enough this is also what Herb Sutter states in the linked article

At least one popular C++ compiler (Microsoft’s, up to version 7.x) parses exception specifications but does not actually enforce them, reducing the exception specifications to glorified comments

Finally, this answer is more a curiosity, throw() has been deprecated (and also removed) in its various forms from the more recent versions of the language: https://en.cppreference.com/w/cpp/language/except_spec .

Prefer noexcept: https://en.cppreference.com/w/cpp/language/noexcept_spec