Topic: try blocks & compound statements


Author: Tim <zickus@eecis.udel.edu>
Date: 1995/09/28
Raw View
Greetings,

I am curious as to why the try block has the syntax of:

 try <compound-statement> <handler-list>


instead of:

 try <statement> <handler-list>


The specific context which prompted me to investigate this issue is
that of a constructor which can throw an exception:


 class CFoo {

  class FooError { };

  CFoo(int bar) { if (bar>4) throw(FooError); }
 }

 ...

 {

     try {
         CFoo x(1);

         // x is destructed here!
     }

     catch (FooError) {
     ...
     }

     x.SomeMember(); // error: x is out of scope here
 }


Note that because the compount statement is required, x is created
and destroyed within the try block.

If the try block could be written without the compound statement, i.e.

 try CFoo x(1);

 catch (FooError) {
     ...
 }

 x.SomeMember(); // ok, x is still in scope


then this scoping issue does not arise.

I realize that this can be worked-around using a larger try block that
encompasses the entire life-span of the constructed object, or by using
"new" and a pointer that exists before the try block.  Both of these
solutions seem less palatable in some situations than using the single
statement.

comments welcome!

regards,

- Tim

--
--
 Tim Zickus                         "On my fourth day of telecommuting,
 zickus@eecis.udel.edu               I realized that clothes are totally
 http://www.eecis.udel.edu/~zickus   unnecessary"                - Dilbert

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/09/29
Raw View
In article 95Sep28101903@physics2.Berkeley.EDU, Tim <zickus@eecis.udel.edu> writes:
>
>I am curious as to why the try block has the syntax of:
>
> try <compound-statement> <handler-list>
>
>instead of:
>
> try <statement> <handler-list>

That issue was discussed. It would be possible to omit the compound-statement
requirement, but then you need a special rule for "dangling handlers"
similar to the rule for "dangling else's":
 try  try  f();
 catch(T) { ... } // which 'try'?
(It isn't a problem, it's just another special rule.)

You would also have a subtle semicolon determining the appilication of handlers:
 try
  try
   f();
  catch( T1 ) { ... };
  catch( T2 ) { ... }
 catch( T3 ) { ... }
The "catch T2" really belongs to the outer try, not to the inner try.

Requiring braces means we don't need a special rule for the first example.
You are less likely to make the grouping error of the second example when
you need a pair of braces instead of a single semicolon.

(I know you are not going to write "try try", but the language definition
and compilers and teachers and users of the language have to deal with all
the rules. And you might wind up with the equivalent of "try try" if the
controlled statement is a comma-expression ending with a "try".)

> {
>
>     try {
>         CFoo x(1);
>
>         // x is destructed here!
>     }
>
>     catch (FooError) {
>     ...
>     }
>
>     x.SomeMember(); // error: x is out of scope here
> }

Move all the stuff dealing with x inside the try block and you don't have
a problem. I believe you can always do that with little or no loss of clarity.

---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]