Topic: Exiting catch block using goto?


Author: "Andrew R. Thomas-Cramer" <artc@prism-cs.com>
Date: 1999/11/24
Raw View

David R Tribble wrote in message <383B358E.7960BD3B@tribble.com>...
>Andrew R. Thomas-Cramer wrote:
>>
>> A "finally" block, similar to Java's, would allow the same effect
>> without the use of a goto.
>> Yes, we can also accomplish the same effect now by placing the
>> finally block in the destructor of a local variable of a
>> locally-defined class -- but less readably.
>
>Or by using an extra try/catch nesting level:


Except:
* Performance might differ between a language-supported finally clause and a
solution that requires exceptions to be thrown in non-exceptional cases.
* To be equivalent in effect (besides performance) to a finally clause, you
need to rethrow the original exception in the outermost catch iff the
exception wasn't the hack exception thrown at the end of the normal try
block.




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW <allan_w@my-deja.com>
Date: 1999/11/23
Raw View
In article <38343B47.1D478428@sun.com>,
  Steve Clamage <stephen.clamage@sun.com> wrote:
> Leaving a handler does not cause any technical difficulties. The
> pending exception is deemed handled upon entry to the block.

Entry?

Are these two code snippets equivalent?

    bool caught = false;
    try {
        func();
    } catch {
        caught = true;
        std::cout << "There's an exception!" << std::endl;
        throw;
    }

vs.

    bool caught = false;
    try {
        func();
    } catch {
        caught = true;
    }
    if (caught) {
        std::cout << "There's an exception!" << std::endl;
        throw;
    }

The second version tries to re-throw, but it's no longer in
the handler. Is this legal?

My guess is: No, the second version isn't legal. By exiting
the handler, the pending exception was considered handled.
Once it's no longer pending it can no longer be re-thrown.

If you're right that the exception is considered handled
on entry to the handler block, then my explanation is not
valid. Neither of the two snippets should work, or (more
likely) both of them should work. Is "throw" always able
to re-throw the most recent exception, handled or not?

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/11/23
Raw View
AllanW wrote:
>
> In article <38343B47.1D478428@sun.com>,
>   Steve Clamage <stephen.clamage@sun.com> wrote:
> > Leaving a handler does not cause any technical difficulties. The
> > pending exception is deemed handled upon entry to the block.
>
> Entry?

C++ Standard 15.3/8:

"An exception is considered handled upon entry to a handler. [Note: the
stack will have been unwound at that point. ]"

"Handled" means the exception is no longer active; throwing another
exception is ok. It doesn't mean the program has no other actions
to perform as a result of catching the exception.

> Are these two code snippets equivalent?
>
>     bool caught = false;
>     try {
>         func();
>     } catch {
>         caught = true;
>         std::cout << "There's an exception!" << std::endl;
>         throw;
>     }
>
> vs.
>
>     bool caught = false;
>     try {
>         func();
>     } catch {
>         caught = true;
>     }
>     if (caught) {
>         std::cout << "There's an exception!" << std::endl;
>         throw;
>     }
>
> The second version tries to re-throw, but it's no longer in
> the handler. Is this legal?

No and No. A throw expression without an operand is allowed only
inside a handler, and throws the exception that was caught (15.6/1).

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrew R. Thomas-Cramer" <artc@prism-cs.com>
Date: 1999/11/24
Raw View
    A "finally" block, similar to Java's, would allow the same effect
without the use of a goto.
    Yes, we can also accomplish the same effect now by placing the finally
block in the destructor of a local variable of a locally-defined class --
but less readably.

Stephen Howe wrote in message <80pgf9$ki6$1@soap.pipex.net>...
>I have drawn a blank looking at Stroustrup's 3rd edition.
>
>I would like to know if it is legal to exit a catch block as demonstrated
>below (not my code) under the ISO/ANSI C++ standard? Also, would it have
>been ok under the ARM?
>






Author: David R Tribble <david@tribble.com>
Date: 1999/11/24
Raw View
Andrew R. Thomas-Cramer wrote:
>
> A "finally" block, similar to Java's, would allow the same effect
> without the use of a goto.
> Yes, we can also accomplish the same effect now by placing the
> finally block in the destructor of a local variable of a
> locally-defined class -- but less readably.

Or by using an extra try/catch nesting level:

    void foo()
    {
        try    // Extra try/catch wrapper
        {
            try   // [A]
            {
                doSomething();     // Might throw
            }
            catch (Exception &e)
            {
                err = 1;
                throw 1;           // a la 'goto fail'
            }

            try   // [B]
            {
                doSomethingElse(); // Might throw
            }
            catch (Exception &e)
            {
                err = 1;
                throw 2;           // a la 'goto fail'
            }

            //throw 0;             // (see below)
         }
         catch (int x)
         {
    fail:
             recover();
             cleanUp();
         }
    }

The catch(int) block isn't exactly the same as a finally block,
unless we uncomment the throw(0) statement, i.e., unless we ensure
that all execution paths flow into the catch(int) block.

In general, a series of code blocks that all jump to a label at the
end of the function block (i.e., simulating a 'finally' clause)
can be replaced by a try/catch block and throws.

-- David R. Tribble, david@tribble.com, http://david.tribble.com --

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/11/19
Raw View
"Stephen Howe" <sjhowe@dial.pipex.com> writes:
> I would like to know if it is legal to exit a catch block as demonstrated
> below (not my code) under the ISO/ANSI C++ standard? Also, would it have
> been ok under the ARM?

6.6.4 clearly states that this is permitted. The only restrictions
on transfers are given by 6.7/3, which prohibit jumping into the
scope of an initialized variable from outside that scope.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/11/19
Raw View
Stephen Howe wrote:
>
> I have drawn a blank looking at Stroustrup's 3rd edition.
>
> I would like to know if it is legal to exit a catch block as demonstrated
> below (not my code) under the ISO/ANSI C++ standard? Also, would it have
> been ok under the ARM?

>From C++ standard, clause 15, paragraph 2:

"A goto, break, return, or continue statement can be used to transfer
control out of a try block or handler, but not into one."

(A catch block is a handler.)

Leaving a handler does not cause any technical difficulties. The
pending exception is deemed handled upon entry to the block. You can
leave any block whenever you want to.

Of course, goto's have their own conceptual problems regarding
flow of control, and all the other rules about goto's apply.
That is, you can't bypass an initialization unless you bypass
the block containing the initialization, and you cannot jump
into various kinds of structures (like try-blocks and handlers).

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Stephen Howe" <sjhowe@dial.pipex.com>
Date: 1999/11/17
Raw View
I have drawn a blank looking at Stroustrup's 3rd edition.

I would like to know if it is legal to exit a catch block as demonstrated
below (not my code) under the ISO/ANSI C++ standard? Also, would it have
been ok under the ARM?

Many thanks.

Stephen Howe

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void somefunction() {
  future_price *fp = 0;
  // more stuff here ...

  try {
     fp= new future_price( day, fc->get_symbol(), fc->get_exchange_abrev(),
fc->get_year_mo(), __price);
  } catch (StandardError) {
    errorflag=1;
    goto end;
  }

  try {
     fp->update_or_insert();
  } catch (StandardError) {
    errorflag = 1;
    goto end;
  }

  // other statement here simular to the previous

  // clean up at end
  end:

  if (pf!=0) delete pf;
  if (fp!=0) delete fp;
  if (fc!=0) delete fc;
  if (fut!=0) delete fut;

  if (errorflag) {
    cout.flush();
    throw StandardError();
  }
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]