Skip to main content

4.7 Qualified Expressions


This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue


[A qualified_expression is used to state explicitly the type, and to verify the subtype, of an operand that is either an expression or an aggregate. ]



qualified_expression ::=
subtype_mark'(expression) | subtype_mark'aggregate

Name Resolution Rules


The expected type for the operand (the expression or aggregate) is determined by the subtype_mark. Furthermore, the operand shall resolve to be either the specified expected type or a universal type that covers it.


The first sentence defines the expected type for rules that assume one is defined. The second sentence prevents the use of the various implicit conversions that are usually allowed for expected types (except the one for numeric literals). The intent is that a qualified expression is similar to an assertion about the subtype of the operand, and thus implicit conversions would interfere with that intent.

Static Semantics


[If the operand of a qualified_expression denotes an object, the qualified_expression denotes a constant view of that object.] The nominal subtype of a qualified_expression is the subtype denoted by the subtype_mark.


This is stated in 3.3.

Dynamic Semantics


The evaluation of a qualified_expression evaluates the operand (and if of a universal type, converts it to the type determined by the subtype_mark) and checks that its value belongs to the subtype denoted by the subtype_mark. The exception Constraint_Error is raised if this check fails. Furthermore, if predicate checks are enabled for the subtype denoted by the subtype_mark, a check is performed as defined in 3.2.4 that the value satifies the predicates of the subtype.


This is one of the few contexts in Ada 95 where implicit subtype conversion is not performed prior to a constraint check, and hence no “sliding” of array bounds is provided.


The effect of a failed predicate check is as defined in 3.2.4; such a check could raise any exception, not just Constraint_Error or Assertion_Error.


Implicit subtype conversion is not provided because a qualified_expression with a constrained target subtype is essentially an assertion about the subtype of the operand, rather than a request for conversion. An explicit type_conversion can be used rather than a qualified_expression if subtype conversion is desired.


We do a predicate check here so that a qualified_expression never allows something that the equivalent type_conversion would not allow.


NOTE When a given context does not uniquely identify an expected type, a qualified_expression can be used to do so. In particular, if an overloaded name or aggregate is passed to an overloaded subprogram, it can be necessary to qualify the operand to resolve its type.



Examples of disambiguating expressions using qualification:


type Mask is (Fix, Dec, Exp, Signif); type Code is (Fix, Cla, Dec, Tnz, Sub); 8 Print (Mask'(Dec)); -- Dec is of type Mask Print (Code'(Dec)); -- Dec is of type Code 9/5

for J in Code'(Fix) .. Code'(Dec) loop ... -- qualification is necessary for either Fix or Dec for J in Code range Fix .. Dec loop ... -- qualification unnecessary for J in Code'(Fix) .. Dec loop ... -- qualification unnecessary for Dec 10 Dozen'(1 | 3 | 5 | 7 => 2, others => 0) -- see 4.6

Wording Changes from Ada 2005


Added a definition of the nominal subtype of a qualified_expression.

Inconsistencies With Ada 2012


Corrigendum: A qualified_expression now performs a predicate check for the named subtype (if it is enabled). Original Ada 2012 did not include that check (an omission). While this is formally inconsistent (an exception could be raised when none would be raised by original Ada 2012), cases where this scenario arises are likely to be rare (the qualified expression would have to have a stricter subtype than the following usage) and the check is more likely to detect bugs than be unexpected.

Wording Changes from Ada 2012


Reworded the resolution rule so that the operand of a qualified_expression has an expected type. This eliminates an annoying inconsistency in the language definition.