4.5.9 Declare Expressions
{
AI12-0236-1}
Declare expressions
provide a
way to declare local constants and object renamings in an expression
context.
Syntax
Reason: We allow
(declare begin
expression)
with no
declare_items,
for uniformity with block statements, which also allow a pointless
declare.
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
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.
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).
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.
{
AI22-0045-1}
In previous versions of Ada, pragmas cannot appear
inside of an expression, and thus, global settings cannot be changed
within an expression. Implementations can and do depend on this property.
Therefore, we do not want to allow any pragmas that might change a global
setting. For simplicity and portability, we only allow executable pragmas
(which never affect compile-time settings) rather than attempting to
determine which pragmas are a problem (which is likely to differ between
implementations).
Name Resolution Rules
Dynamic Semantics
Ramification: {
AI22-0017-1}
If the evaluation of a declare_expression
is not a master (see 7.6.1) then objects
declared therein may still exist (and have pending finalization) after
the evaluation of the declare_expression
has completed. This is consistent with the handling of other objects
created by subexpressions, such as those created by the evaluation of
aggregates
or function calls.
Examples
{
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):
{
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
Incompatibilities With Ada 2022
{
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.
Extensions to Ada 2022
{
AI22-0045-1}
Executable pragmas (such as
pragma Assert) are now allowed in declare expressions. Ada 2022 did not
intend to allow any pragmas in declare expressions.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe