Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

3.7.1 Discriminant Constraints

A discriminant_constraint specifies the values of the discriminants for a given discriminated type.

Language Design Principles

{AI05-0299-1} The rules in this subclause clause are intentionally parallel to those given in 4.3.1, “Record Aggregates”. 


discriminant_constraint ::= 
   (discriminant_association {, discriminant_association})
discriminant_association ::= 
   [discriminant_selector_name {| discriminant_selector_name} =>] expression
A discriminant_association is said to be named if it has one or more discriminant_selector_names; it is otherwise said to be positional. In a discriminant_constraint, any positional associations shall precede any named associations. 

Name Resolution Rules

Each selector_name of a named discriminant_association shall resolve to denote a discriminant of the subtype being constrained; the discriminants so named are the associated discriminants of the named association. For a positional association, the associated discriminant is the one whose discriminant_specification occurred in the corresponding position in the known_discriminant_part that defined the discriminants of the subtype being constrained.
The expected type for the expression in a discriminant_association is that of the associated discriminant(s). 

Legality Rules

{8652/0008} {AI95-00168-01} {AI95-00363-01} {AI05-0041-1} A discriminant_constraint is only allowed in a subtype_indication whose subtype_mark denotes either an unconstrained discriminated subtype, or an unconstrained access subtype whose designated subtype is an unconstrained discriminated subtype. However, in the case of an a general access subtype, a discriminant_constraint is legal only if any dereference of a value of the access type is known to be constrained (see 3.3) illegal if the designated type has a partial view that is constrained or, for a general access subtype, has default_expressions for its discriminants there is a place within the immediate scope of the designated subtype where the designated subtype's view is constrained. In addition to the places where Legality Rules normally apply (see 12.3), these rules apply also in the private part of an instance of a generic unit. In a generic body, this rule is checked presuming all formal access types of the generic might be general access types, and all untagged discriminated formal types of the generic might have default_expressions for their discriminants.
This paragraph was deleted.Reason: {8652/0008} {AI95-00168-01} {AI95-00363-01} The second rule is necessary to prevent assignments that change the discriminant of a constrained object. See the defect report for examples.
Reason: {AI95-00363-01} The second rule is necessary to prevent objects from changing so that they no longer match their constraint. In Ada 95, we attempted to prevent this by banning every case where an aliased object could be unconstrained or be changed by an enclosing assignment. New ways to cause this problem were being discovered frequently, meaning that new rules had to be dreamed up to cover them. Meanwhile, aliased objects and components were getting more and more limited. In Ada 2005, we sweep away all of that cruft and replace it by a simple rule “thou shalt not create an access subtype that can point to an item whose discriminants can be changed by assignment”. 
Discussion: {AI05-0041-1} The second rule will only use the indefinite or dereference bullets in the definition of “known to be constrained”. The rule is worded in terms of “known to be constrained” in order to capture the special rules that apply in generic bodies (rather than repeating them and getting them subtly wrong). 
A named discriminant_association with more than one selector_name is allowed only if the named discriminants are all of the same type. A discriminant_constraint shall provide exactly one value for each discriminant of the subtype being constrained.
This paragraph was deleted.{AI05-0102-1} The expression associated with an access discriminant shall be of a type convertible to the anonymous access type.
Ramification: In addition, 8.6 requires that the expression associated with an access discriminant is convertible (see 4.6) to the anonymous access type. This implies both convertibility of designated types, and static accessibility. This implies that if an object of type T with an access discriminant is created by an allocator for an access type A, then it requires that the type of the expression associated with the access discriminant have an accessibility level that is not statically deeper than that of A. This is to avoid dangling references.

Dynamic Semantics

A discriminant_constraint is compatible with an unconstrained discriminated subtype if each discriminant value belongs to the subtype of the corresponding discriminant.
Ramification: The "dependent compatibility check" has been eliminated in Ada 95. Any checking on subcomponents is performed when (and if) an object is created.
Discussion: There is no need to define compatibility with a constrained discriminated subtype, because one is not allowed to constrain it again.
A composite value satisfies a discriminant constraint if and only if each discriminant of the composite value has the value imposed by the discriminant constraint.
For the elaboration of a discriminant_constraint, the expressions in the discriminant_associations are evaluated in an arbitrary order and converted to the type of the associated discriminant (which might raise Constraint_Error — see 4.6); the expression of a named association is evaluated (and converted) once for each associated discriminant. The result of each evaluation and conversion is the value imposed by the constraint for the associated discriminant.
Reason: We convert to the type, not the subtype, so that the definition of compatibility of discriminant constraints is not vacuous.
59  The rules of the language ensure that a discriminant of an object always has a value, either from explicit or implicit initialization. 
Discussion: Although it is illegal to constrain a class-wide tagged subtype, it is possible to have a partially constrained class-wide subtype: If the subtype S is defined by T(A => B), then S'Class is partially constrained in the sense that objects of subtype S'Class have to have discriminants corresponding to A equal to B, but there can be other discriminants defined in extensions that are not constrained to any particular value. 


 {AI05-0299-1} Examples (using types declared above in subclause clause 3.7): 
Large   : Buffer(200);  --  constrained, always 200 characters
                        --   (explicit discriminant value)
Message : Buffer;       --  unconstrained, initially 100 characters
                        --   (default discriminant value)
Basis   : Square(5);    --  constrained, always 5 by 5
Illegal : Square;       --  illegal, a Square has to be constrained

Inconsistencies With Ada 83

Dependent compatibility checks are no longer performed on subtype declaration. Instead they are deferred until object creation (see 3.3.1). This is upward compatible for a program that does not raise Constraint_Error.

Wording Changes from Ada 83

Everything in RM83-3.7.2(7-12), which specifies the initial values for discriminants, is now redundant with 3.3.1, 6.4.1, 8.5.1, and 12.4. Therefore, we don't repeat it here. Since the material is largely intuitive, but nevertheless complicated to state formally, it doesn't seem worth putting it in a "NOTE." 

Incompatibilities With Ada 95

{8652/0008} {AI95-00168-01} {AI95-00363-01} The Corrigendum added a restriction on discriminant_constraints for general access subtypes. Such constraints are prohibited if the designated type can be treated as constrained somewhere in the program. Ada 2005 goes further and prohibits such discriminant_constraints if the designated type has (or might have, in the case of a formal type) defaults for its discriminants. The use of general access subtypes is rare, and this eliminates a boatload of problems that required many restrictions on the use of aliased objects and components (now lifted). Similarly, Ada 2005 prohibits discriminant_constraints on any access type whose designated type has a partial view that is constrained. Such a type will not be constrained in the heap to avoid privacy problems. Again, the use of such subtypes is rare (they can only happen within the package and its child units). 

Wording Changes from Ada 2005

{AI05-0041-1} Correction: Revised the rules on access subtypes having discriminant constraints to depend on the “known to be constrained” rules. This centralizes the rules so that future fixes need to be made in only one place, as well as fixing bugs in obscure cases.
{AI05-0102-1} Correction: Moved implicit conversion Legality Rule to 8.6. 

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