!standard 7.3.3(7/5) 23-01-12 AI22-0051-1/02
!class Binding Interpretation 22-10-26
!status work item 22-10-26
!status received 22-10-26
!subject Preelaborable_Initialization and contract aspects
A Default_Initial_Condition expression is evaluated when a default-initialized object is created. The aspect Preelaborable_Initialization (P_I) does not take into account any such evaluation when it determines whether a component has P_I. That means that such an evaluation could execute operations not otherwise allowed during the elaboration of a preelaborated package (in particular, calling a function other than the handful allowed for preelaboration). This seems to
circumvent the purpose of aspect P_I.
This problem occurs in a number of cases, not just Default_Initial_Condition.
(1) The Default_Initial_Condition is evaluated for any default-initialized object of the type associated with the aspect (see 7.3.3(7/5)).
(2) The Type_Invariant is evaluated for any default-initialized object of the type associated with the aspect (see 7.3.2(10/4)).
(3) A Dynamic_Predicate can be evaluated for any default-initialized object of a type with a Default_Value (since the value is converted to the appropriate subtype, and that subtype can have a Dynamic_Predicate, see 3.3.1(11.1/5)). [Note: A Static_Predicate cannot evaluate anything that is not preelaborable.]
(4) A Dynamic_Predicate can be evaluated for any default-initialized object of a type with a Default_Component_Value (since the component value is converted to the appropriate subtype, see 3.3.1(13/5)). Case (3) can also happen for an array object (that also is mentioned in 3.3.1(13/5)).
(5) A Dynamic_Predicate can be evaluated for any component of a default-initialized object if the component has a default expression; again, the component is converted to the appropriate subtype, see 3.3.1(13/5).
None of these cases are covered by the current wording in 10.2.1. It might appear that case (5) is covered by 10.2.1(11.3/2), but it is not; that paragraph talks about the evaluation of the default expression; it does not say anything about the subtype conversion that happens afterward.
Note that the simple solution of not allowing a type that runs afoul of any of these cases to have Preelaborable_Initialization would make it impossible to have a preelaborable package that uses Default_Initial_Condition (D_I_C). A D_I_C is only allowed on a private type, and as such, any useful D_I_C necessarily has to make at least one function call to query the state of the object. So we need a more complex solution (perhaps singling out D_I_C for special rules).
The Ada.Containers packages illustrate this issue nicely. Following is the specification of the Ada.Containers.Vectors package, showing just the parts relevant to this discussion:
The elaboration of a default-initialized Vector object will finish with the evaluation of the Default_Initial_Condition expression. That will call the function Length. However, that means that such an elaborable construct is not preelaborable by the rules given in 10.2.1(5, 7). Yet we are asserting that this construct is preelaborable by the use of the P_I aspect.
*** TBD. We’ll need tests for whatever rule is adopted, but we need to decide on a rule before we can say what kind of tests are needed.
This AI was promoted from AI12-0420-1, which was put into the Hold state as it was reported too late to find a solution in time to make the deadline for Ada 2022. This AI is associated with Github Issue #30 (https://github.com/Ada-Rapporteur-Group/User-Community-Input/issues/30).