catch(...) doesn't catch everything

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Adam

    #1

    catch(...) doesn't catch everything

    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.

  • red floyd

    #2
    Re: catch(...) doesn't catch everything

    Adam wrote:[color=blue]
    > 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.
    >[/color]

    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.

    Comment

    • red floyd

      #3
      Re: catch(...) doesn't catch everything

      Adam wrote:[color=blue]
      > 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";
      > }
      > }
      >[/color]

      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.

      Comment

      • red floyd

        #4
        Re: catch(...) doesn't catch everything

        red floyd wrote:[color=blue]
        > Adam wrote:[color=green]
        >> 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";
        >> }
        >> }
        >>[/color]
        >
        > 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.
        >[/color]

        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.

        Comment

        • Marcus Kwok

          #5
          Re: catch(...) doesn't catch everything

          Adam <adam@scan.mc.x erox.com> wrote:[color=blue]
          > 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.[/color]

          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

          Comment

          • red floyd

            #6
            Re: catch(...) doesn't catch everything

            Marcus Kwok wrote:[color=blue]
            >[/color]
            [color=blue]
            > 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.
            >[/color]

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

            Comment

            • Marek Vondrak

              #7
              Re: catch(...) doesn't catch everything

              >> main()[color=blue][color=green]
              >> {
              >> try {
              >> throw;
              >> } catch (...) {
              >> std::cerr << "Caught exception\n";
              >> }
              >> }[/color][/color]
              [color=blue]
              > 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.[/color]

              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




              Comment

              • Adam

                #8
                Re: catch(...) doesn't catch everything

                >> Standard, 15.1/8 "If no exception is presently being handled, executing[color=blue][color=green]
                >> 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.[/color]
                >
                >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.[/color]

                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.

                Comment

                • Marcus Kwok

                  #9
                  Re: catch(...) doesn't catch everything

                  red floyd <no.spam@here.d ude> wrote:[color=blue]
                  > Marcus Kwok wrote:[color=green]
                  >>[/color]
                  >[color=green]
                  >> 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.
                  >>[/color]
                  > In the second case, terminate() is called (15.1/8).[/color]

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

                  --
                  Marcus Kwok

                  Comment

                  • red floyd

                    #10
                    Re: catch(...) doesn't catch everything

                    Marek Vondrak wrote:[color=blue][color=green][color=darkred]
                    >>> main()
                    >>> {
                    >>> try {
                    >>> throw;
                    >>> } catch (...) {
                    >>> std::cerr << "Caught exception\n";
                    >>> }
                    >>> }[/color][/color]
                    >[color=green]
                    >> 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.[/color]
                    >
                    > 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.
                    >[/color]
                    Good point. "throw;" not in a catch block, should compile. I guess
                    that's what 15.1/8 is for.

                    Comment

                    Working...