πŸš€ go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by Philippe Verdy Tue, 09 Apr 1996 16:58
Re: Must exception classes have copy constructors?
#3969
Author: Philippe Verdy
Date: Tue, 09 Apr 1996 16:58
177 lines
8602 bytes
David Byrden <Goyra@iol.ie> s'Γ©crit :
> Alan Griffiths <aGriffiths@ma.ccngroup.com> wrote:
> >Looking through the DWP I can't see any reason to require a copy 
> >constructor, but there are references to copying temporaries.
>           What DWP did you read? The January 96 version requires that the 
> "throw" statement have access to the copy constructor and destructor of a 
> thrown object.
          I have submitted an article which has been rejected
(I don't know why) about copy constructors needed. What I meant
is such a restriction about the copy constructor is only to
allow cleaner exception handling, concerning stack unrolling.
In effect, if the compiler dis not have access to the copy
constructor, the exception catcher which effectively matches
the exception in the current context should be limited to
use references only on the object.

Because an error catcher can catch only a base class of the
thrown object, and not the full object, when the exception
matches, the thrown object will have to be copied to a catcher
variable which may have less members than the original thrown
object. This copy will occur while the throwing function con-
text is still active, because the original thrown object was
constructed within the thrower and may still reference some
fields which will be destructed by the stack unrolling algo-
rithm once the catcher receives the focus to do the appro-
priate action the handler require.

The reason why I am putting this submission is that I don't
know why this scheme does not allow resumable exceptions:
after all, when an assertion fails in a function which has
to throw an exception, it first constructs an exception object
within its context, then calls a library function to perform
the exception matching. Once the matching is found, this
library first call the exception handler to perform the
copy constructor to a temporary object with type equal to
the one taken by the catcher. Then only the library returns
to the exception thrower, which will perform sannity in its
context, and return to its caller in exception state (may be
by returning an extra flag in a register, or by modifying
its return address to an laternate return address given by
its caller, so that the caller can continue stack unrolling
on its active block and eventually jump to the catcher block
if the calling block was a try { } block.

So if the catcher has temporarily access to the thrower's
context which is still valid, I think that exceptions can
be resumed:
instead of just performing the copy contructor of the 
catched exception, the library could first enter into a
status function whose execution will say if the exception
can be recovered or not. If it cannot, this context can be
chained to other pending resumable catchers, until one of
them return a status that says the exception can be resumed.

If no resumable catcher is found in this chain, then the
library will return a "don't-resume" status to the thrower
which will effectively destroy its own exception object, then
will start the stack unrolling for an effective exception.

But if a catcher returns a "resume" status, this status can
be immediately returned to the thrower, which will continue
as if the exception had not occured.

This has several impacts on the code specification, because
the programmer should have to specify whever its throw()
invocation could resume or not. So this requires an additional
keyword like throw_resumable(), which does not have the "goto"
or "break" or "continue" or "return" semantics, in the fact
that the exception is not fatal (the jump is conditional).
The compiler would generate a different library call for this
addtional operator.

By the same way, a resumable error catcher could fail to find
a way which will satisfy the resume condition indicated by
the exception object. But there could be other resumable
catchers pending. This gives the opportunity of the resumable
exception catchers chain (this only adds a unique static code
pointer in each execution thread). The rest of the storage for
this chain can be allocated at the catch point.

Finally, resumable exception handlers must indicate that they
can resume the exception. The semantics of the standard 
catch() construct is not sufficient for it as the catcher code
to execute is not od the same kind: a standard catch()
handler executes its code once the exception has occured, in a
constext where the thrower does not exists any more.
So this requires another keyword or construction like
catch_resumable() instead of catch().

For this new construction, the copy constructor does not have
to be invoked, because the thrower context is still valid, so
a catch_resumable() handler can receive directly a reference
to the thrown object. The code in that catcher must be quite
short if the exception kind is a lack of resource, because
the thrower context is still active.

In order to indicate its intention of resuming the exception,
this code should use a specific construct (for example: retry;
without parameters, which means "cancel the pending exception
and resume to the resumable thrower"). This would make the
resumable catcher return a "resume" state to the exception
library which will be reported to the thrower. In that case
all it would have to do is just delete its temporary thrown
object and continue the execution.

Such resumable exceptions should be very useful for time-out
exceptions, or device-not-ready exceptions (which may be
resumed after the user has been noticed of it by an alert
with choices like "Retry" or "Cancel"), or for exceptions
caused by lack of resources (a resumable exception catcher
could check if it can free up some of the resources indicated
by the exception object, for example it could free up some
unused cache-buffers to allow more memory for the thrower).

This model has no-impact on the existing code, and will add
overhead only when new keywords are in actions. All other
semantics of stancard throw()/catch() pairs are preserved.
What do you think of this model ?

Example of resumable exceptions for out-of-memory:
--------------
in the catcher
--------------
struct OutOfMemory; // fatal exception
struct NeedMemory
: public OutOfMemory // resumable exception
{
  NeedMemory(size_t size) : OutOfMemory(size) {}
}
...
try {
  ...
  function() // this can send a resumable exception
  ...
}
catch_resumable(NeedMemory &exc) {
  // check if can free up some memory for exc.size()
  if (can_resume == true)
    retry; // resume in the thrower
} // cannot resume, check other catch_resumable() handlers now
catch(OutOfMemory &exc) {
  // Fatal exception, or resumable exception could not be
  // resumed by an explicit use of "retry;" in any pending
  // resumable_catchers.
  // Make some cleanup required by this error.
} // continue at end of try/catch construct

----------------------------------
Now in the exception thrower code:
----------------------------------
void function()
{
   size_t size;
   ...
   int retries;
   for (retries = 2; --retries >= 0) {
     // needs some memory resource (size_t size)
     ...
     if (...can allocate size...)
        break; // exits the for loop
     if (retries == 0)
        throw OutOfMemory(size); // fatal
     throw_resumable NeedMemory(size);
     // if could resume, continue here
   } // retry loop
   if (retries < 0)
     throw OutOfMemory(size); // fatal
   // OK, resource allocation succeeded
   ...
}
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]
Re: Must exception classes have copy const
#3974
Author: Steve Clamage
Date: Tue, 09 Apr 1996 20:01
42 lines
2627 bytes
In article 347@dub-news-svc-5.compuserve.com, Philippe Verdy <100105.3120@compuserve.com> writes:
>
>The reason why I am putting this submission is that I don't
>know why this scheme does not allow resumable exceptions:

Whether exceptions should be resumable was the subject of intense debate
over a period of two years early in the life of the C++ Committee. The
debate was not about how to implement them. The debate was about whether
the resumable model was appropriate for C++.

The short answer is that resumable exceptions impose a much higher
cost on all implementations and programs, even those that don't
want resumable exceptions, and that although sometimes you do want
to resume an exception, such cases are in practice rare. People with
extensive experience with resumable exceptions came to believe over
time that they were a mistake, and that you get better program designs 
if you don't use them. 

You can simulate resumable exceptions with non-resumable exceptions
if you need to, so only convenience and not functionality is lost by
the adopted language rule.

Debugging is a special case. In debug mode, you want to halt at the throw
point, not the catch point after the stack has been unwound. A reasonable
debugger will let you halt at the throw point.

Whether an uncaught exception is detected before or after stack unwinding
is up to the implementation. The implementation can choose to provide
a core dump or other diagnostic information as of the point of the
uncaught throw, for example, and reasonable implementations will make
that choice available.
---
Steve Clamage, stephen.clamage@eng.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads