catch(...) doesn't catch everything

Discussion in 'C++' started by Adam, Feb 1, 2006.

  1. Adam

    Adam Guest

    I was looking for a way to just catch any exception throw. Given the
    postings, it looks like catch(...) should do it, except it doesn't.
    Maybe C++ is suppose to work this way, or maybe this is a bug in g++.

    I have a small program to demonstrate below. I compiled on a RH9
    system using g++ v3.4.5.

    #include <iostream>

    main()
    {
    try {
    throw(1);
    } catch (...) {
    std::cerr << "Caught integer exception\n";
    }

    try {
    throw;
    } catch (...) {
    std::cerr << "Caught exception\n";
    }
    }

    The first exception is caught when an integer is thrown. The second
    one isn't caught.

    I just need to capture an exception because of a possible error in a
    constructor (so I can't pass back an error code). I don't need to send
    any information in the exception, so I was just using throw without any
    arguments. Looks like I'll need to send something just so it works
    unless I'm doing something wrong.
    Adam, Feb 1, 2006
    #1
    1. Advertising

  2. Adam

    red floyd Guest

    Adam wrote:
    > I was looking for a way to just catch any exception throw. Given the
    > postings, it looks like catch(...) should do it, except it doesn't.
    > Maybe C++ is suppose to work this way, or maybe this is a bug in g++.
    >
    > I have a small program to demonstrate below. I compiled on a RH9
    > system using g++ v3.4.5.
    >
    > #include <iostream>
    >
    > main()
    > {
    > try {
    > throw(1);
    > } catch (...) {
    > std::cerr << "Caught integer exception\n";
    > }
    >
    > try {
    > throw;
    > } catch (...) {
    > std::cerr << "Caught exception\n";
    > }
    > }
    >
    > The first exception is caught when an integer is thrown. The second
    > one isn't caught.
    >
    > I just need to capture an exception because of a possible error in a
    > constructor (so I can't pass back an error code). I don't need to send
    > any information in the exception, so I was just using throw without any
    > arguments. Looks like I'll need to send something just so it works
    > unless I'm doing something wrong.
    >


    to be honest, I'm surprised that the second one even compiled. The
    argumentless version of throw is for use inside a catch clause, to
    rethrow the caught exception.
    red floyd, Feb 1, 2006
    #2
    1. Advertising

  3. Adam

    red floyd Guest

    Adam wrote:
    > I was looking for a way to just catch any exception throw. Given the
    > postings, it looks like catch(...) should do it, except it doesn't.
    > Maybe C++ is suppose to work this way, or maybe this is a bug in g++.
    >
    > I have a small program to demonstrate below. I compiled on a RH9
    > system using g++ v3.4.5.
    >
    > #include <iostream>
    >
    > main()
    > {
    > try {
    > throw(1);
    > } catch (...) {
    > std::cerr << "Caught integer exception\n";
    > }
    >
    > try {
    > throw;
    > } catch (...) {
    > std::cerr << "Caught exception\n";
    > }
    > }
    >


    Actually, on further review, your code is behaving properly.

    Standard, 15.1/8 "If no exception is presently being handled, executing
    a throw-expression with no operand calls terminate(). Since your second
    throw is not in an exception handler (catch clause), your program calls
    terminate(). Go to terminate(), go directly to terminate(), do not pass
    GO, do not collect $200.
    red floyd, Feb 1, 2006
    #3
  4. Adam

    red floyd Guest

    red floyd wrote:
    > Adam wrote:
    >> I was looking for a way to just catch any exception throw. Given the
    >> postings, it looks like catch(...) should do it, except it doesn't.
    >> Maybe C++ is suppose to work this way, or maybe this is a bug in g++.
    >>
    >> I have a small program to demonstrate below. I compiled on a RH9
    >> system using g++ v3.4.5.
    >>
    >> #include <iostream>
    >>
    >> main()
    >> {
    >> try {
    >> throw(1);
    >> } catch (...) {
    >> std::cerr << "Caught integer exception\n";
    >> }
    >>
    >> try {
    >> throw;
    >> } catch (...) {
    >> std::cerr << "Caught exception\n";
    >> }
    >> }
    >>

    >
    > Actually, on further review, your code is behaving properly.
    >
    > Standard, 15.1/8 "If no exception is presently being handled, executing
    > a throw-expression with no operand calls terminate(). Since your second
    > throw is not in an exception handler (catch clause), your program calls
    > terminate(). Go to terminate(), go directly to terminate(), do not pass
    > GO, do not collect $200.
    >


    Damn. Missed a close quote. The quote from the Standard ends before
    the word "Since". So the text should read '... operand calls
    terminate()."' Everything from "Since your second..." is my commentary.
    red floyd, Feb 1, 2006
    #4
  5. Adam

    Marcus Kwok Guest

    Adam <> wrote:
    > I was looking for a way to just catch any exception throw. Given the
    > postings, it looks like catch(...) should do it, except it doesn't.
    > Maybe C++ is suppose to work this way, or maybe this is a bug in g++.
    >
    > I have a small program to demonstrate below. I compiled on a RH9
    > system using g++ v3.4.5.
    >
    > #include <iostream>
    >
    > main()
    > {
    > try {
    > throw(1);
    > } catch (...) {
    > std::cerr << "Caught integer exception\n";
    > }
    >
    > try {
    > throw;
    > } catch (...) {
    > std::cerr << "Caught exception\n";
    > }
    > }
    >
    > The first exception is caught when an integer is thrown. The second
    > one isn't caught.
    >
    > I just need to capture an exception because of a possible error in a
    > constructor (so I can't pass back an error code). I don't need to send
    > any information in the exception, so I was just using throw without any
    > arguments. Looks like I'll need to send something just so it works
    > unless I'm doing something wrong.


    IIRC, throw with no arguments will simply re-throw the current
    exception; it is usually used in cases that need to perform local
    cleanup before propagating the exception further up the stack. In the
    second case, there is no current exception, so nothing is thrown.

    --
    Marcus Kwok
    Marcus Kwok, Feb 1, 2006
    #5
  6. Adam

    red floyd Guest

    Marcus Kwok wrote:
    >


    > IIRC, throw with no arguments will simply re-throw the current
    > exception; it is usually used in cases that need to perform local
    > cleanup before propagating the exception further up the stack. In the
    > second case, there is no current exception, so nothing is thrown.
    >


    In the second case, terminate() is called (15.1/8).
    red floyd, Feb 2, 2006
    #6
  7. >> main()
    >> {
    >> try {
    >> throw;
    >> } catch (...) {
    >> std::cerr << "Caught exception\n";
    >> }
    >> }


    > to be honest, I'm surprised that the second one even compiled. The
    > argumentless version of throw is for use inside a catch clause, to rethrow
    > the caught exception.


    Yes, but the question of whether "throw;" is being invoked in the context of
    a catch block can not be generally decided in the compile time. Consider the
    following example:

    void f()
    {
    throw; // (1)
    }

    void g()
    {
    try { throw 1; } catch ( ... ) { f(); } // (2)
    }

    When the compiler generates code for (1), it can not issue a diagnostic
    because "throw;" is perfectly valid when it is called from a catch block, as
    in (2). Therefore, the actual behaviour depends on the current execution
    path of the program and is determined in the run time.

    Regards
    Marek
    Marek Vondrak, Feb 2, 2006
    #7
  8. Adam

    Adam Guest

    >> Standard, 15.1/8 "If no exception is presently being handled, executing
    >> a throw-expression with no operand calls terminate(). Since your second
    >> throw is not in an exception handler (catch clause), your program calls
    >> terminate(). Go to terminate(), go directly to terminate(), do not pass
    >> GO, do not collect $200.

    >
    >Damn. Missed a close quote. The quote from the Standard ends before
    >the word "Since". So the text should read '... operand calls
    >terminate()."' Everything from "Since your second..." is my commentary.


    Thanks for the information. Now I understand why the code acts like it
    does. Guess I'll just have to give an argument to throw to catch it.
    Adam, Feb 2, 2006
    #8
  9. Adam

    Marcus Kwok Guest

    red floyd <> wrote:
    > Marcus Kwok wrote:
    >>

    >
    >> IIRC, throw with no arguments will simply re-throw the current
    >> exception; it is usually used in cases that need to perform local
    >> cleanup before propagating the exception further up the stack. In the
    >> second case, there is no current exception, so nothing is thrown.
    >>

    > In the second case, terminate() is called (15.1/8).


    Thanks, I saw it in your other post after I had already posted mine.

    --
    Marcus Kwok
    Marcus Kwok, Feb 2, 2006
    #9
  10. Adam

    red floyd Guest

    Marek Vondrak wrote:
    >>> main()
    >>> {
    >>> try {
    >>> throw;
    >>> } catch (...) {
    >>> std::cerr << "Caught exception\n";
    >>> }
    >>> }

    >
    >> to be honest, I'm surprised that the second one even compiled. The
    >> argumentless version of throw is for use inside a catch clause, to rethrow
    >> the caught exception.

    >
    > Yes, but the question of whether "throw;" is being invoked in the context of
    > a catch block can not be generally decided in the compile time. Consider the
    > following example:
    >
    > void f()
    > {
    > throw; // (1)
    > }
    >
    > void g()
    > {
    > try { throw 1; } catch ( ... ) { f(); } // (2)
    > }
    >
    > When the compiler generates code for (1), it can not issue a diagnostic
    > because "throw;" is perfectly valid when it is called from a catch block, as
    > in (2). Therefore, the actual behaviour depends on the current execution
    > path of the program and is determined in the run time.
    >

    Good point. "throw;" not in a catch block, should compile. I guess
    that's what 15.1/8 is for.
    red floyd, Feb 2, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. zetasum
    Replies:
    0
    Views:
    461
    zetasum
    Feb 18, 2005
  2. John Black
    Replies:
    8
    Views:
    4,132
    Xenos
    Aug 20, 2004
  3. Replies:
    10
    Views:
    1,166
    Twisted
    Jul 16, 2007
  4. Marteno Rodia

    catch doesn't catch a thrown exception

    Marteno Rodia, Aug 3, 2009, in forum: Java
    Replies:
    5
    Views:
    540
    Daniel Pitts
    Aug 5, 2009
  5. Rotwang
    Replies:
    3
    Views:
    282
    Rotwang
    Apr 25, 2012
Loading...

Share This Page