4.7 Qualified Expressions


4.7 Qualified Expressions

1 [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. {type conversion: See also qualified_expression}]


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

Name Resolution Rules

3 {operand (of a qualified_expression) [partial]} The operand (the expression or aggregate) shall resolve to be of the type determined by the subtype_mark, or a universal type that covers it. 

Dynamic Semantics

4 {evaluation (qualified_expression) [partial]} {Range_Check [partial]} {check, language-defined (Range_Check)} {Discriminant_Check [partial]} {check, language-defined (Discriminant_Check)} {Index_Check [partial]} {check, language-defined (Index_Check)} 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. {implicit subtype conversion (qualified_expression) [partial]} {Constraint_Error (raised by failure of run-time check)} The exception Constraint_Error is raised if this check fails. 

4.a Ramification: 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. 

4.b Reason: 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. 


5 (23)  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 might be necessary to qualify the operand to resolve its type. 


6 Examples of disambiguating expressions using qualification: 

type Mask is (Fix, Dec, Exp, Signif);
type Code is (Fix, Cla, Dec, Tnz, Sub);


Print (Mask'(Dec));  --  Dec is of type Mask
Print (Code'(Dec));  --  Dec is of type Code


for J in Code'(Fix) .. Code'(Dec) loop ... -- qualification needed 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


Dozen'(1 | 3 | 5 | 7 => 2, others => 0)    -- see 4.6