[Home] [Prev] [Next] [Index]

11.4 Exception Handling

11.4 Exception Handling

1
When an exception is raised, normal program execution is abandoned and control is transferred to an exception handler. The selection of this handler depends on whether the exception is raised during the execution of statements or during the elaboration of declarations.

2
References:

*
declaration 3.1

*
elaboration 3.1

*
elaboration 3.9

*
exception 11

*
exception handler 11.2

*
raising of exceptions 11.3

*
statement 5

11.4.1 Exceptions Raised During the Execution of Statements

1
The handling of an exception raised by the execution of a sequence of statements depends on whether the innermost frame or accept statement that encloses the sequence of statements is a frame or an accept statement. The case where an accept statement is innermost is described in section 11.5. The case where a frame is innermost is presented here.

2
Different actions take place, depending on whether or not this frame has a handler for the exception, and on whether the exception is raised in the sequence of statements of the frame or in that of an exception handler.

3
If an exception is raised in the sequence of statements of a frame that has a handler for the exception, execution of the sequence of statements of the frame is abandoned and control is transferred to the exception handler. The execution of the sequence of statements of the handler completes the execution of the frame (or its elaboration if the frame is a package body).

4
If an exception is raised in the sequence of statements of a frame that does not have a handler for the exception, execution of this sequence of statements is abandoned. The next action depends on the nature of the frame:

5 (a)
For a subprogram body, the same exception is raised again at the point of call of the subprogram, unless the subprogram is the main program itself, in which case execution of the main program is abandoned.

6 (b)
For a block statement, the same exception is raised again immediately after the block statement (that is, within the innermost enclosing frame or accept statement).

7 (c)
For a package body that is a declarative item, the same exception is raised again immediately after this declarative item (within the enclosing declarative part). If the package body is that of a subunit, the exception is raised again at the place of the corresponding body stub. If the package is a library unit, execution of the main program is abandoned.

8 (d)
For a task body, the task becomes completed.

9
An exception that is raised again (as in the above cases (a), (b), and (c)) is said to be propagated, either by the execution of the subprogram, the execution of the block statement, or the elaboration of the package body. No propagation takes place in the case of a task body. If the frame is a subprogram or a block statement and if it has dependent tasks, the propagation of an exception takes place only after termination of the dependent tasks.

10
Finally, if an exception is raised in the sequence of statements of an exception handler, execution of this sequence of statements is abandoned. Subsequent actions (including propagation, if any) are as in the cases (a) to (d) above, depending on the nature of the frame.

11
Example:

function FACTORIAL (N : POSITIVE) return FLOAT is
begin
        if N = 1 then
                return 1.0;
        else
                return FLOAT(N) * FACTORIAL(N-1);
        end if;
exception
        when NUMERIC_ERROR => return FLOAT'SAFE_LARGE;
end FACTORIAL;

12
If the multiplication raises NUMERIC_ERROR, then FLOAT'SAFE_LARGE is returned by the handler. This value will cause further NUMERIC_ERROR exceptions to be raised by the evaluation of the expression in each of the remaining invocations of the function, so that for large values of N the function will ultimately return the value FLOAT'SAFE_LARGE.

13
Example:

procedure P is
        ERROR : exception;
        procedure R;

        procedure Q is
        begin
                R;
                ... -- error situation (2)
        exception
                ...
                when ERROR => -- handler E2
                ...
        end Q;

        procedure R is
        begin
                ...        -- error situation (3)
        end R;

begin
        ...         -- error situation (1)
        Q;
        ...
exception
        ...
        when ERROR =>         -- handler E1
        ...
end P;

14
The following situations can arise:

15 (1)
If the exception ERROR is raised in the sequence of statements of the outer procedure P, the handler E1 provided within P is used to complete the execution of P.

16 (2)
If the exception ERROR is raised in the sequence of statements of Q, the handler E2 provided within Q is used to complete the execution of Q. Control will be returned to the point of call of Q upon completion of the handler.

17 (3)
If the exception ERROR is raised in the body of R, called by Q, the execution of R is abandoned and the same exception is raised in the body of Q. The handler E2 is then used to complete the execution of Q, as in situation (2).

18
Note that in the third situation, the exception raised in R results in (indirectly) transferring control to a handler that is part of Q and hence not enclosed by R. Note also that if a handler were provided within R for the exception choice others, situation (3) would cause execution of this handler, rather than direct termination of R.

19
Lastly, if ERROR had been declared in R, rather than in P, the handlers E1 and E2 could not provide an explicit handler for ERROR since this identifier would not be visible within the bodies of P and Q. In situation (3), the exception could however be handled in Q by providing a handler for the exception choice others.

Notes:

20
The language does not define what happens when the execution of the main program is abandoned after an unhandled exception.

21
The predefined exceptions are those that can be propagated by the basic operations and the predefined operators.

22
The case of a frame that is a generic unit is already covered by the rules for subprogram and package bodies, since the sequence of statements of such a frame is not executed but is the template for the corresponding sequences of statements of the subprograms or packages obtained by generic instantiation.

23
References:

*
accept statement 9.5

*
basic operation 3.3.3

*
block statement 5.6

*
body stub 10.2

*
completion 9.4

*
declarative item 3.9

*
declarative part 3.9

*
dependent task 9.4

*
elaboration 3.1

*
elaboration 3.9

*
exception 11

*
exception handler 11.2

*
frame 11.2

*
generic instantiation 12.3

*
generic unit 12

*
library unit 10.1

*
main program 10.1

*
numeric_error exception 11.1

*
package 7

*
package body 7.1

*
predefined operator 4.5

*
procedure 6.1

*
sequence of statements 5.1

*
statement 5

*
subprogram 6

*
subprogram body 6.3

*
subprogram call 6.4

*
subunit 10.2

*
task 9

*
task body 9.1

11.4.2 Exceptions Raised During the Elaboration of Declarations

1
If an exception is raised during the elaboration of the declarative part of a given frame, this elaboration is abandoned. The next action depends on the nature of the frame:

2 (a)
For a subprogram body, the same exception is raised again at the point of call of the subprogram, unless the subprogram is the main program itself, in which case execution of the main program is abandoned.

3 (b)
For a block statement, the same exception is raised again immediately after the block statement.

4 (c)
For a package body that is a declarative item, the same exception is raised again immediately after this declarative item, in the enclosing declarative part. If the package body is that of a subunit, the exception is raised again at the place of the corresponding body stub. If the package is a library unit, execution of the main program is abandoned.

5 (d)
For a task body, the task becomes completed, and the exception TASKING_ERROR is raised at the point of activation of the task, as explained in section 9.3.

6
Similarly, if an exception is raised during the elaboration of either a package declaration or a task declaration, this elaboration is abandoned; the next action depends on the nature of the declaration.

7 (a)
For a package declaration or a task declaration, that is a declarative item, the exception is raised again immediately after the declarative item in the enclosing declarative part or package specification. For the declaration of a library package, the execution of the main program is abandoned.

8
An exception that is raised again (as in the above cases (a), (b), (c) and (e)) is said to be propagated, either by the execution of the subprogram or block statement, or by the elaboration of the package declaration, task declaration or package body.

9
Example of an exception in the declarative part of a block statement (case (b)):

procedure P is
        ...
begin
        declare
                N : INTEGER := F;                 -- the function F may raise ERROR
        begin
                ...
        exception
                when ERROR =>        -- handler E1
        end;
        ...
exception
        when ERROR => -- handler E2
end P;

-- if the exception ERROR is raised in the declaration of N, it
-- is handled by E2

10
References:

*
activation 9.3

*
block statement 5.6

*
body stub 10.2

*
completed task 9.4

*
declarative item 3.9

*
declarative part 3.9

*
elaboration 3.1

*
elaboration 3.9

*
exception 11

*
frame 11.2

*
library unit 10.1

*
main program 10.1

*
package body 7.1

*
package declaration 7.1

*
package specification 7.1

*
subprogram 6

*
subprogram body 6.3

*
subprogram call 6.4

*
subunit 10.2

*
task 9

*
task body 9.1

*
task declaration 9.1

*
tasking_error exception 11.1



[Home] [Prev] [Next] [Index]

documentation@rational.com
Copyright © 1993-2000, Rational Software Corporation. All rights reserved.