T
terminator
I found the following as the ANSI C++ std behavior of the exception
handling mechanism in the documentation of my compiler:
Control reaches the try statement by normal sequential execution. The
guarded section within the try block is executed.
If no exception is thrown during execution of the guarded section, the
catch clauses that follow the try block are not executed. Execution
continues at the statement after the last catch clause following the
try block in which the exception was thrown.
If an exception is thrown during execution of the guarded section or
in any routine the guarded section calls (either directly or
indirectly), an exception object is created from the object created by
the throw operand. (This implies that a copy constructor may be
involved.) At this point, the compiler looks for a catch clause in a
higher execution context that can handle an exception of the type
thrown (or a catch handler that can handle any type of exception). The
catch handlers are examined in order of their appearance following the
try block. If no appropriate handler is found, the next dynamically
enclosing try block is examined. This process continues until the
outermost enclosing try block is examined.
If a matching handler is still not found, or if an exception occurs
while unwinding, but before the handler gets control, the predefined
run-time function terminate is called. If an exception occurs after
throwing the exception, but before the unwind begins, terminate is
called.
If a matching catch handler is found, and it catches by value, its
formal parameter is initialized by copying the exception object. If it
catches by reference, the parameter is initialized to refer to the
exception object. After the formal parameter is initialized, the
process of unwinding the stack begins. This involves the destruction
of all automatic objects that were constructed (but not yet
destructed) between the beginning of the try block associated with the
catch handler and the exception's throw site. Destruction occurs in
reverse order of construction. The catch handler is executed and the
program resumes execution following the last handler (that is, the
first statement or construct which is not a catch handler). Control
can only enter a catch handler through a thrown exception, never via a
goto statement or a case label in a switch statement.
I do not feel much doubt about the standardness of the above context ,
but IMO the std could be more elegant with the some minor
modifications;
i.It looks as if the stack unwinding is performed at 'throw'
site .but IMHO if the stack unwinding is left to the 'catch' site the
program will be more flexible;because it gives us the option to handle
the trouble and resume the program from the statement after the
throw ,rather than stopping what was performing before the
throw.Therefore a default exception handler also need be implicitly
defined ,so that it can catch all exeptions and do nothing but unwind
the stack and terminate.
ii.Appliction of some existing keywords can be extended:
1.default:
The 'default' keyword can be introduced as an acceptable parameter to
the 'throw' statement as the uncatchable(unhandleable) exception which
cannot be cought by any catch block except the implicitly defined
default handler ,so that a 'throw default' performs a secure exit on
current thread:
try{
throw default;/*unwind the stack completely ,then terminate this
thread.*/
}catch(...){
//shall never be reached:cannot catch the default exception.
}
2.break:
A 'break' statement inside a catch block - that does not belong to any
loop or 'switch' statement - must break the catch block:
try{
throw "serious but not fatal";
}catch(...){
A ca;
B cb;
if(condition) break;//goto end;
do_something();
end:
}/* cb.~B(); ca.~A();*/
3.continue:
A 'continue' statement inside a catch block - that does not belong to
any loop - must mean that the exception has been resolved and the
program should resume from the first statement after the 'throw' that
has raised or re-thrown the exception :
try{
throw "throw 1";
keep_on1:
do_something();
}cathch(const char *){
try{
throw;//re-throw
keep_on2:
continue;/*go to keep_on1 as if every thing were ok.*/
}catch(...){
continue;/*go to keep_on2 as if no ecxeption has occured*/
}
}
Thus if a catch block owns a 'continue' statment,the compiler should
postpone stack unwinding to exiting from the catch block - either
normally or via a 'break' or 'goto' to outside the catch block- rather
than the beginning of catch block.
regards,
FM.
handling mechanism in the documentation of my compiler:
Control reaches the try statement by normal sequential execution. The
guarded section within the try block is executed.
If no exception is thrown during execution of the guarded section, the
catch clauses that follow the try block are not executed. Execution
continues at the statement after the last catch clause following the
try block in which the exception was thrown.
If an exception is thrown during execution of the guarded section or
in any routine the guarded section calls (either directly or
indirectly), an exception object is created from the object created by
the throw operand. (This implies that a copy constructor may be
involved.) At this point, the compiler looks for a catch clause in a
higher execution context that can handle an exception of the type
thrown (or a catch handler that can handle any type of exception). The
catch handlers are examined in order of their appearance following the
try block. If no appropriate handler is found, the next dynamically
enclosing try block is examined. This process continues until the
outermost enclosing try block is examined.
If a matching handler is still not found, or if an exception occurs
while unwinding, but before the handler gets control, the predefined
run-time function terminate is called. If an exception occurs after
throwing the exception, but before the unwind begins, terminate is
called.
If a matching catch handler is found, and it catches by value, its
formal parameter is initialized by copying the exception object. If it
catches by reference, the parameter is initialized to refer to the
exception object. After the formal parameter is initialized, the
process of unwinding the stack begins. This involves the destruction
of all automatic objects that were constructed (but not yet
destructed) between the beginning of the try block associated with the
catch handler and the exception's throw site. Destruction occurs in
reverse order of construction. The catch handler is executed and the
program resumes execution following the last handler (that is, the
first statement or construct which is not a catch handler). Control
can only enter a catch handler through a thrown exception, never via a
goto statement or a case label in a switch statement.
I do not feel much doubt about the standardness of the above context ,
but IMO the std could be more elegant with the some minor
modifications;
i.It looks as if the stack unwinding is performed at 'throw'
site .but IMHO if the stack unwinding is left to the 'catch' site the
program will be more flexible;because it gives us the option to handle
the trouble and resume the program from the statement after the
throw ,rather than stopping what was performing before the
throw.Therefore a default exception handler also need be implicitly
defined ,so that it can catch all exeptions and do nothing but unwind
the stack and terminate.
ii.Appliction of some existing keywords can be extended:
1.default:
The 'default' keyword can be introduced as an acceptable parameter to
the 'throw' statement as the uncatchable(unhandleable) exception which
cannot be cought by any catch block except the implicitly defined
default handler ,so that a 'throw default' performs a secure exit on
current thread:
try{
throw default;/*unwind the stack completely ,then terminate this
thread.*/
}catch(...){
//shall never be reached:cannot catch the default exception.
}
2.break:
A 'break' statement inside a catch block - that does not belong to any
loop or 'switch' statement - must break the catch block:
try{
throw "serious but not fatal";
}catch(...){
A ca;
B cb;
if(condition) break;//goto end;
do_something();
end:
}/* cb.~B(); ca.~A();*/
3.continue:
A 'continue' statement inside a catch block - that does not belong to
any loop - must mean that the exception has been resolved and the
program should resume from the first statement after the 'throw' that
has raised or re-thrown the exception :
try{
throw "throw 1";
keep_on1:
do_something();
}cathch(const char *){
try{
throw;//re-throw
keep_on2:
continue;/*go to keep_on1 as if every thing were ok.*/
}catch(...){
continue;/*go to keep_on2 as if no ecxeption has occured*/
}
}
Thus if a catch block owns a 'continue' statment,the compiler should
postpone stack unwinding to exiting from the catch block - either
normally or via a 'break' or 'goto' to outside the catch block- rather
than the beginning of catch block.
regards,
FM.