Annotated Ada Reference Manual (Ada 202y Draft 1)Legal Information
Contents   Index   References   Search   Previous   Next 

11.3 Raise Statements and Raise Expressions

1
[A raise_statement raises an exception.] 

Syntax

2/2
{AI95-00361-01} raise_statement ::= raise;
      | raise exception_name [with string_expression];
2.1/4
{AI12-0022-1} {AI12-0152-1} raise_expression ::= raise exception_name [with string_simple_expression]
2.2/4
{AI12-0152-1} If a raise_expression appears within the expression of one of the following contexts, the raise_expression shall appear within a pair of parentheses within the expression:
2.3/4
object_declaration;
2.4/4
modular_type_definition;
2.5/4
floating_point_definition;
2.6/4
ordinary_fixed_point_definition;
2.7/4
decimal_fixed_point_definition;
2.8/4
default_expression;
2.9/4
ancestor_part.
2.a.1/4
Reason: Unlike conditional expressions, this doesn't say "immediately surrounded"; the only requirement is that it is somehow within a pair of parentheses that is part of the expression. We need this restriction in order that raise_expressions cannot be syntactically confused with immediately following constructs (such as aspect_specifications).
2.a.2/4
Discussion: We only need to require that a right parenthesis appear somewhere between the raise_expression and the surrounding context; that's all we need to specify in order to eliminate the ambiguities. Moreover, we don't care at all where the left parenthesis is (so long as it is legal, of course).
2.a.3/4
For instance, the following is illegal by this rule: 
2.a.4/4
Obj : Boolean := Func_Call or else raise TBD_Error with Atomic;
2.a.5/4
as the "with Atomic" could be part of the raise_expression or part of the object declaration. Both of the following are legal: 
2.a.6/4
Obj : Boolean := Func_Call or else (raise TBD_Error) with Atomic;
Obj : Boolean := (Func_Call or else raise TBD_Error) with Atomic;
2.a.7/4
and if the with belongs to the raise_expression, then both of the following are legal: 
2.a.8/4
Obj : Boolean := Func_Call or else (raise TBD_Error with Atomic);
Obj : Boolean := (Func_Call or else raise TBD_Error with Atomic);
2.a.9/4
This rule only requires parentheses for raise_expressions that are part of the "top-level" of an expression in one of the named contexts; the raise_expression is either the entire expression, or part of a chain of logical operations. In practice, the raise_expression will almost always be last in interesting top-level expressions; anything that follows it could never be executed, so that should be rare. Other contexts such as conditional expressions, qualified expressions, aggregates, and even function calls, provide the needed parentheses. All of the following are legal, no additional parens are needed: 
2.a.10/4
Pre : Boolean  := (if not Is_Valid(Param) then raise Not_Valid_Error);
A : A_Tagged   := (Some_Tagged'(raise TBD_Error) with Comp => 'A');
B : Some_Array := (1, 2, 3, others => raise Not_Valid_Error);
C : Natural    := Func (Val => raise TBD_Error);
2.a.11/4
Parentheses that are part of the context of the expression don't count. For instance, the parentheses around the raise_expression are required in the following: 
2.a.12/4
D : A_Tagged   := ((raise TBD_Error) with Comp => 'A');
2.a.13/4
as ancestor_part is one of the contexts that triggers the rule.
2.a.14/4
This English-language rule could have been implemented instead by adding nonterminals initial_expression and initial_relation, which are the same as choice_expression and choice_relation except for the inclusion of membership in initial_relation. Then, initial_expresion could be used in place of expression in all of the contexts noted. We did not do that because of the large amount of change required, both to the grammar and to language rules that refer to the grammar. A complete grammar is given in AI12-0152-1.
2.a.15/4
The use of a raise_expression is illegal in each of modular_type_definition, floating_point_definition, ordinary_fixed_point_definition, and decimal_fixed_point_definition as these uses are required to be static and a raise_expression is never static. We include these in this rule so that Ada text has an unambiguous syntax in these cases. 

Legality Rules

3/4
{AI12-0022-1} {AI12-0159-1} The exception_name, if any, of a raise_statement or raise_expression shall denote an exception. A raise_statement with no exception_name (that is, a re-raise statement) shall be within a handler, but not within a body enclosed by that handler. 

Name Resolution Rules

3.1/4
 {AI95-00361-01} {AI12-0022-1} {AI12-0152-1} The string_expression or string_simple_expression, if any, of a raise_statement or raise_expression is expected to be of type String.
3.2/4
 {AI12-0022-1} {AI12-0159-1} The expected type for a raise_expression shall be any single type. 

Dynamic Semantics

4/4
{AI95-00361-01} {AI12-0022-1} {AI12-0152-1} To raise an exception is to raise a new occurrence of that exception[, as explained in 11.4]. For the execution of a raise_statement with an exception_name, the named exception is raised. Similarly, for the evaluation of a raise_expression, the named exception is raised. [In both of these cases, if a string_expression or string_simple_expression is present, the expression is evaluated and its value is associated with the exception occurrence.] For the execution of a re-raise statement, the exception occurrence that caused transfer of control to the innermost enclosing handler is raised [again]. 
4.a.1/2
Proof: {AI95-00361-01} The definition of Exceptions.Exception_Message includes a statement that the string is returned (see 11.4.1). We describe the use of the string here so that we don't have an unexplained parameter in this subclause. 
4.a
Implementation Note: For a re-raise statement, the implementation does not create a new Exception_Occurrence, but instead propagates the same Exception_Occurrence value. This allows the original cause of the exception to be determined. 
4.b/5
Term entry: raise an exception — abandon normal program execution so as to draw attention to the fact that the corresponding situation has arisen
4.1/4
NOTE   {AI12-0062-1} {AI12-0152-1} {AI12-0159-1} If the evaluation of a string_expression or string_simple_expression raises an exception, that exception is propagated instead of the one denoted by the exception_name of the raise_statement or raise_expression.

Examples

5
Examples of raise statements: 
6/2
{AI95-00433-01} raise Ada.IO_Exceptions.Name_Error;   -- see A.13
raise Queue_Error with "Buffer Full"; -- see 9.11
7
raise;                                -- re-raise the current exception
8/5
{AI12-0312-1} -- For an example of a raise expression, see the Streams Subsystem definitions in 13.13.1.

Wording Changes from Ada 83

8.a
The fact that the name in a raise_statement has to denote an exception is not clear from RM83. Clearly that was the intent, since the italicized part of the syntax rules so indicate, but there was no explicit rule. RM83-1.5(11) doesn't seem to give the italicized parts of the syntax any force. 

Extensions to Ada 95

8.b/2
{AI95-00361-01} The syntax of a raise_statement is extended to include a string message. This is more convenient than calling Exceptions.Exception_Message (exception_name'Identity, string_expression), and should encourage the use of message strings when raising exceptions.

Extensions to Ada 2012

8.c/4
{AI12-0022-1} {AI12-0152-1} {AI12-0159-1} Corrigendum: The raise_expression is new. This construct is necessary to allow conversion of existing specifications to use preconditions and predicates without changing the exceptions raised. It is considered important enough to be added to Ada 2012 rather than waiting for Ada 2022. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe