Topic: exceptions and object lifetime


Author: richard@ex-parrot.com ("Richard Smith")
Date: Fri, 27 Sep 2002 15:32:14 +0000 (UTC)
Raw View
"Grzegorz Sakrejda" <sakrejda@pacbell.net> wrote in message
news:Xns928D90A96379Asakrejdapacbellnet@64.164.98.29...
> Have anyone considered exception handling model based on the object
>  lifetime.
> I mean that construction of the object would be considered as a start
>  of the try block, destruction of the object as an end to try block,
>  + some catch member functions that are invoked if an exception is thrown.

This sounds a bit like something that Andrei Alexandrescu (I think) was
trying to do earlier this year.  As I recall, he was trying to write a class
like

   class scoped_exception_handler
   {
   public:
    ~scoped_exception_handler()
     {
       try { throw; } // or similar [*]
       catch ( const std::exception &ex ) { handle_exception( ex ); }
     }

   private:
     void handle_exception( const std::exception &ex )
     {
       std::cout << "An exception occured" << std::endl;
     }
   };

which would allow you to write

   int main()
   {
     {
       my_scoped_exception_handler eh;
       throw std::runtime_error( "Error" );
     } // destructor of eh handles the exception.
   }

Unfortunately, I don't think anyone came up with a legal way of writing the
line marked [*].  Still, it's was nice idea, and I for one would like it to
be possible to do something like this.

--
Richard Smith


---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: sakrejdanospam@pacbell.net (Grzegorz Sakrejda)
Date: Thu, 26 Sep 2002 18:56:01 +0000 (UTC)
Raw View
allan_w@my-dejanews.com (Allan W) wrote in
<7f2735a5.0209220017.57c9dbe6@posting.google.com>:
 [snip]
>> >Exception processing is very different from longjump, not least
>> >because destructors are executed.

Yes, and this is a piece of code that doesn't have possibility
 to catch an exception. Why?

>>
>>  That's why catching exception in the destructor would look so
>>  natural, at least question whether destructor can throw an exception
>>  will be gone.
>
>Seems it would make it worse. Not only could you still throw from a
>destructor, but it's now more likely that there would already be
>an existing exception when the destructor runs... or else, I'm
>completely mis-reading your whole proposal (which is likely, sorry).

As above, I would like to have possibility to catch en exception
 before destructor is executed, what will happen next is
 for programer to choose. Current problem is that i cannot protect
 destructor against exception, so destructor shouldn't throw,
 and both are restrictions.
>
 [snip]
>
>
>Okay. But I still get confused when there's multiple objects.
>
>    myClass myArray[10];
>    int main() { throw 10; }
>
>Which myArray element would catch? Chances are that myArray[9] was
>the last one constructed -- would it therefore catch?

 Yes, most of the rules are there. myArray[9] could catch and
     throw again, to myArray[8]...
  A little bit funny , but why array of objects that could catch.

>
>I'm beginning to understand how this proposal works, but not how
>it helps to organize code. The object being destructed has a chance
>to catch some error, regardless of where it was thrown. If you
>have trouble tracing the call stack backwards towards main, in order
>to figure out where an exception would be caught -- wouldn't allowing
>an object's destruction to catch exception just multiply this
>complexity?

Yes , I realized that the benefits of this could be proved only
 by some examples showing how it works and why it is better then
 current mechanism . It will increase complexity.


--
 grzegorz

 // please remove nospam when replying by email

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 23 Sep 2002 14:37:08 +0000 (UTC)
Raw View
> >sakrejda@pacbell.net (Grzegorz Sakrejda) wrote
> >> Have anyone considered exception handling model based on the object
> >>  lifetime.
> >> I mean that construction of the object would be considered as a start
> >>  of the try block, destruction of the object as an end to try block,
> >>  + some catch member functions that are invoked if an exception is
> >>  thrown.

> allan_w@my-dejanews.com (Allan W) wrote
> >There's a reason that they used the name "exceptions" instead of the
> >name "errors." Exceptions do NOT neccesarily imply that data is corrupt,
> >or that any other error has occurred. Look up the English-language
> >meaning of "exception" -- it means something unusual, nothing more.

gsakrejda@hotmail.com (Grzegorz Sakrejda) wrote
> Yes , but C++ exceptions are generated by software,
>      code cannot deal with the data , at least not in the typical way.

How so?

> >>  - I don't have anything against current exception mechanism
> >>    but the use of it is quite tedious. We are back again
> >>    into the world of long jump where throwing an exception will move
> >
> >Exception processing is very different from longjump, not least
> >because destructors are executed.
>
>  That's why catching exception in the destructor would look so natural,
>  at least question whether destructor can throw an exception will be gone.

Seems it would make it worse. Not only could you still throw from a
destructor, but it's now more likely that there would already be
an existing exception when the destructor runs... or else, I'm
completely mis-reading your whole proposal (which is likely, sorry).

> >>    us to the code that is hard to find.
> >>    In addition try/catch brackets are quite verbose and hide
> >>     a structure of an algorithm
> >>    This would not happen with exception handling inserted into the
> >>    class It's already there, hidden.
> >
> >On the contrary, once you understand how try/catch works, it's very
> >easy to find the code that will catch any given error. Simply look
> >in the current function, then it's caller, and so on up the call tree.
>
>  That's exactly the point , this tree can have a lot of branches,
>   i mean function calls can be all  other the program, and in every place
>   try /catch clause is required.

Are you saying, "when function foo() throws an exception, the
compiler rolls a dice to choose which function catches it?" 'Cause
if so, you're simply mistaken.

Or, are you saying "there might be 100 different functions that call
foo() directly or indirectly, and therefore any one of them might be
called upon to catch the error?" Because if that's it -- well, that's
the whole point of exceptions. An unusual situation has developed,
and now it's up to the caller to deal with it (or else pass the buck
to whoever called it).

> >By contrast, moving catches into an object WOULD make the catch
> >blocks hard to find -- if that's even possible. There are a huge
> >number of details that would have to be worked out first:
> >
> >   * What happens when two different classes both want to catch
> >     exceptions of the same time?
>
>  Destructors are invoked one after the other, only one
>   pending exception should exist.

In the same way that functions return to their caller one at a time,
so that only one path from main() to foo() exists at runtime...
is that what you're saying?

> >   * You spoke of the lifetime of objects, but sometimes lifetime
> >     extends beyond the scope. How would you handle this:
> >
> >         class myClass {
> >             catch(int x) { /* Or whatever the syntax would be */ }
> >         };
> >         myClass mc(1), *mp=0;

[snip]

> Without catch clause
>
>    int main() {
>      foo(); bar(); baz();
>      }
>   by mc.

...because main() didn't catch it, and mc was constructed before
main() started, right?

>  Pointer would have to be wrapped in a class and exist in an
>      auto/static object to do it.

Okay. But I still get confused when there's multiple objects.

    myClass myArray[10];
    int main() { throw 10; }

Which myArray element would catch? Chances are that myArray[9] was
the last one constructed -- would it therefore catch?

I'm beginning to understand how this proposal works, but not how
it helps to organize code. The object being destructed has a chance
to catch some error, regardless of where it was thrown. If you
have trouble tracing the call stack backwards towards main, in order
to figure out where an exception would be caught -- wouldn't allowing
an object's destruction to catch exception just multiply this complexity?

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 20 Sep 2002 12:00:57 +0000 (UTC)
Raw View
sakrejda@pacbell.net (Grzegorz Sakrejda) wrote
> Have anyone considered exception handling model based on the object
>  lifetime.
> I mean that construction of the object would be considered as a start
>  of the try block, destruction of the object as an end to try block,
>  + some catch member functions that are invoked if an exception is thrown.

That is astonishingly, totally, completely different than what we
have now. There may be merit to the idea, but the complexities are
at least as great as the current mechanism -- I don't think anyone,
including the experts, could understand the ramifications instantly.

> Arguments for that :
>
>  - C++ exceptions are user generated , operations on built in types
>    do not throw exception so this model doesn't exclude anything.
>    Exception means basicly that the data is corrupt, making
>    the handler a part of related object doesn't look like a bad thing.

There's a reason that they used the name "exceptions" instead of the
name "errors." Exceptions do NOT neccesarily imply that data is corrupt,
or that any other error has occurred. Look up the English-language
meaning of "exception" -- it means something unusual, nothing more.

>  - I don't have anything against current exception mechanism
>    but the use of it is quite tedious. We are back again
>    into the world of long jump where throwing an exception will move

Exception processing is very different from longjump, not least
because destructors are executed.

>    us to the code that is hard to find.
>    In addition try/catch brackets are quite verbose and hide
>     a structure of an algorithm
>    This would not happen with exception handling inserted into the class
>    It's already there, hidden.

On the contrary, once you understand how try/catch works, it's very
easy to find the code that will catch any given error. Simply look
in the current function, then it's caller, and so on up the call tree.

By contrast, moving catches into an object WOULD make the catch
blocks hard to find -- if that's even possible. There are a huge
number of details that would have to be worked out first:

   * What happens when two different classes both want to catch
     exceptions of the same time?
   * You spoke of the lifetime of objects, but sometimes lifetime
     extends beyond the scope. How would you handle this:

         class myClass {
             catch(int x) { /* Or whatever the syntax would be */ }
         };
         myClass mc(1), *mp=0;
         int main() {
             foo();
             try { bar(); } catch (int x) { }
             baz();
         }
         void foo() { mp = new myClass(2); }
         void bar() { throw 10; }
         void baz() { delete mp; }
      Would the integer be caught by main, mc, or *mp?

> -  more posiiilities for extending specification, that is adding
>    mechanism for alternative execution, reexecution,
>      virtual exception handling and so on.
>
>  - such model might coexist with the current model.
>
> Most likely this was considered many times.
> Woud you care to give some explanations why this didn't
>  get more attention ?

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gsakrejda@hotmail.com (Grzegorz Sakrejda)
Date: Sat, 21 Sep 2002 19:04:45 +0000 (UTC)
Raw View
allan_w@my-dejanews.com (Allan W) wrote in
<7f2735a5.0209191259.4db6bc2d@posting.google.com>:

>sakrejda@pacbell.net (Grzegorz Sakrejda) wrote
>> Have anyone considered exception handling model based on the object
>>  lifetime.
>> I mean that construction of the object would be considered as a start
>>  of the try block, destruction of the object as an end to try block,
>>  + some catch member functions that are invoked if an exception is
>>  thrown.
>
>That is astonishingly, totally, completely different than what we
>have now. There may be merit to the idea, but the complexities are
>at least as great as the current mechanism -- I don't think anyone,
>including the experts, could understand the ramifications instantly.

 Thank you for the answer, i realized this .

>
>> Arguments for that :
>>
>>  - C++ exceptions are user generated , operations on built in types
>>    do not throw exception so this model doesn't exclude anything.
>>    Exception means basicly that the data is corrupt, making
>>    the handler a part of related object doesn't look like a bad thing.
>
>There's a reason that they used the name "exceptions" instead of the
>name "errors." Exceptions do NOT neccesarily imply that data is corrupt,
>or that any other error has occurred. Look up the English-language
>meaning of "exception" -- it means something unusual, nothing more.

Yes , but C++ exceptions are generated by software,
     code cannot deal with the data , at least not in the typical way.

>
>>  - I don't have anything against current exception mechanism
>>    but the use of it is quite tedious. We are back again
>>    into the world of long jump where throwing an exception will move
>
>Exception processing is very different from longjump, not least
>because destructors are executed.

 That's why catching exception in the destructor would look so natural,
 at least question whether destructor can throw an exception will be gone.

>
>>    us to the code that is hard to find.
>>    In addition try/catch brackets are quite verbose and hide
>>     a structure of an algorithm
>>    This would not happen with exception handling inserted into the
>>    class It's already there, hidden.
>
>On the contrary, once you understand how try/catch works, it's very
>easy to find the code that will catch any given error. Simply look
>in the current function, then it's caller, and so on up the call tree.

 That's exactly the point , this tree can have a lot of branches,
  i mean function calls can be all  other the program, and in every place
  try /catch clause is required.

>
>By contrast, moving catches into an object WOULD make the catch
>blocks hard to find -- if that's even possible. There are a huge
>number of details that would have to be worked out first:
>
>   * What happens when two different classes both want to catch
>     exceptions of the same time?

 Destructors are invoked one after the other, only one
  pending exception should exist.

>   * You spoke of the lifetime of objects, but sometimes lifetime
>     extends beyond the scope. How would you handle this:
>
>         class myClass {
>             catch(int x) { /* Or whatever the syntax would be */ }
>         };
>         myClass mc(1), *mp=0;
>         int main() {
>             foo();
>             try { bar(); } catch (int x) { }
>             baz();
>         }
>         void foo() { mp = new myClass(2); }
>         void bar() { throw 10; }
>         void baz() { delete mp; }
>      Would the integer be caught by main, mc, or *mp?

 By main.

Without catch clause

   int main() {
     foo(); bar(); baz();
     }
  by mc.
 Pointer would have to be wrapped in a class and exist in an
     auto/static object to do it.

 grzegorz

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: sakrejda@pacbell.net (Grzegorz Sakrejda)
Date: Wed, 18 Sep 2002 22:30:53 +0000 (UTC)
Raw View
Have anyone considered exception handling model based on the object
 lifetime.
I mean that construction of the object would be considered as a start
 of the try block, destruction of the object as an end to try block,
 + some catch member functions that are invoked if an exception is thrown.

Arguments for that :

 - C++ exceptions are user generated , operations on built in types
   do not throw exception so this model doesn't exclude anything.
   Exception means basicly that the data is corrupt, making
   the handler a part of related object doesn't look like a bad thing.

 - I don't have anything against current exception mechanism
   but the use of it is quite tedious. We are back again
   into the world of long jump where throwing an exception will move
   us to the code that is hard to find.
   In addition try/catch brackets are quite verbose and hide
    a structure of an algorithm
   This would not happen with exception handling inserted into the class
   It's already there, hidden.

-  more posiiilities for extending specification, that is adding
   mechanism for alternative execution, reexecution,
     virtual exception handling and so on.

 - such model might coexist with the current model.

Most likely this was considered many times.
Woud you care to give some explanations why this didn't
 get more attention ?

 grzegorz



---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]