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

4.5.9 Declare Expressions

1/5
{AI12-0236-1} Declare expressions provide a way to declare local constants and object renamings in an expression context. 

Syntax

2/5
{AI12-0236-1} declare_expression ::= 
    declare {declare_item}
    begin body_expression
3/5
{AI12-0236-1} declare_item ::= object_declaration | object_renaming_declaration
3.a/5
Reason: We allow (declare begin expression) with no declare_items, for uniformity with block statements, which also allow a pointless declare.
4/5
{AI12-0236-1} Wherever the Syntax Rules allow an expression, a declare_expression may be used in place of the expression, so long as it is immediately surrounded by parentheses.
4.a/5
Discussion: The syntactic category declare_expression appears only as a primary that is parenthesized. The above rule allows it to additionally be used in other contexts where it would be directly surrounded by parentheses. This is the same rule that is used for conditional_expressions; see 4.5.7 for a detailed discussion of the meaning and effects of this rule. 

Legality Rules

5/5
{AI12-0236-1} A declare_item that is an object_declaration shall declare a constant of a nonlimited type.
5.a/5
Reason: We disallow limited objects to avoid the horror of task waiting in the middle of an expression. The solution used for controlled objects (wait until the entire expression is finished) isn't appropriate for tasks. This restriction also eliminates build-in-place complexities and the need to activate tasks found in a declare_item.
6/6
{AI12-0236-1} {AI12-0317-1} {AI22-0016-1} A declare_item that is an object_renaming_declaration (see 8.5.1) shall not rename an object of a limited type if any operative constituent of the object_name is part of a value conversion or is part of a newly constructed object (see 4.4).
6.a/5
Reason: We disallow renaming limited temporary objects (like the result of a function call) for the same reasons as for stand-alone objects. We do allow renaming existing limited objects because these don't cause any problems. Note that one cannot directly rename an aggregate, parenthesized expression, conditional_expression, or declare_expression (these are not names), but any of these can appear inside of a qualified_expression or type_conversion (which are names and thus can be renamed). 
7/5
{AI12-0236-1} The following are not allowed within a declare_expression: a declaration containing the reserved word aliased; the attribute_designator Access or Unchecked_Access; or an anonymous access type.
7.a/5
Reason: We do not want to define accessibility rules for declare_items, as nested declare_expressions cause complexities or usage warts. We want to keep this feature simple to use, understand, and implement. Thus, we do not allow any of the features that would require accessibility rules. 

Name Resolution Rules

8/5
{AI12-0236-1} If a declare_expression is expected to be of a type T, then the body_expression is expected to be of type T. Similarly, if a declare_expression is expected to be of some class of types, then the body_expression is subject to the same expectation. If a declare_expression shall resolve to be of a type T, then the body_expression shall resolve to be of type T.
9/5
{AI12-0236-1} The type of a declare_expression is the type of the body_expression.

Dynamic Semantics

10/5
{AI12-0236-1} For the evaluation of a declare_expression, the declare_items are elaborated in order, and then the body_expression is evaluated. The value of the declare_expression is that of the body_expression.

Examples

11/5
{AI12-0236-1} {AI12-0429-1} Example of use of a declare expression as a replacement postcondition for Ada.Containers.Vectors."&" (see A.18.2):
12/5
{AI12-0236-1} with Post =>
   (declare
      Result renames Vectors."&"'Result;
      Length : constant Count_Type := Left.Length + Right.Length;
    begin
      Result.Length = Length and then
      not Tampering_With_Elements_Prohibited (Result) and then
      not Tampering_With_Cursors_Prohibited (Result) and then
      Result.Capacity >= Length)

Extensions to Ada 2012

12.a/5
{AI12-0236-1} Declare expressions are new. 

Incompatibilities With Ada 2022

12.b/6
{AI22-0016-1} Corrigendum: Renaming of limited newly constructed objects is not allowed in a declare_expression in original Ada 2022; this is now extended to any parts of such objects. Thus, a (nonlimited) component or slice of a limited newly constructed object could have been renamed in a declare_expression in original Ada 2022, while such a renaming is illegal in Ada 202y. As declare_expressions are a new feature in Ada 2022, we expect this to be rare. 

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