Each elaboration of a declarative part is independent AI-00809/01 1 90-05-18 ra WI | !standard 03.09 (03) 90-05-18 AI-00809/01 | !class ramification 90-05-18 (provisional classification) | !status work-item 90-05-18 | !status received 89-03-07 | !topic Each elaboration of a declarative part is independent | | !summary 90-05-18 (DRAFT) | | For a given elaboration of a declarative part, the declarative items, if any, | are elaborated in the order in which they are given and each item is | considered to be ALREADY ELABORATED only after its elaboration (without | taking into account whether the item has been elaborated during any other | elaboration of the same declarative part). | | !question 90-05-18 (DRAFT) | | 3.9(3) says: | | The elaboration of a declarative part consists of the elaboration | of the declarative items, if any, in the order in which they are | given in the declarative part. After its elaboration, a | declarative item is said to be ELABORATED. Prior to the | completion of its elaboration (including before the elaboration), | the declarative item is not yet elaborated. | | 3.9(5) then says: | | For a subprogram call, a check is made that the body of the | subprogram is already elaborated. | | Do these paragraphs mean that if a subprogram body is elaborated at least | once during the execution of a program, then it is considered to be "already" | elaborated during any subsequent elaborations of the declarative part? Or is | the elaboration status of a declarative item determined independently each | time a declarative part is elaborated? | | One might think that either interpretation is acceptable -- if the | elaboration check for a subprogram call succeeds once, then it will always | succeed, but the following example shows that this is not the case: | | procedure Q (X : INTEGER) is | procedure R; | | function F return INTEGER is | begin | if X = 1 then | R; -- (1) PROGRAM_ERROR? (yes) | end if; | return 3; | end F; DRAFT DRAFT DRAFT Each elaboration of a declarative part is independent AI-00809/01 2 90-05-18 ra WI | package P is | C : array (1..F) of INTEGER := (others => X); | end P; | | procedure R is begin null; end R; | begin | if X < 1 then | Q(4); -- (2) | end if; | end Q; | | Suppose Q is called with argument -1. R's body will be elaborated after F is | called, but this causes no trouble since R is not invoked during this call to | F. Q will then be called recursively at (2). When Q's declarative part is | elaborated the second time and F is called, R will be called. Is R's body | now considered to be "already elaborated" when R is called at (1) (since its | body was elaborated when Q was called the first time)? | | !response 90-05-18 (DRAFT) | | One of the reasons why a subprogram is not allowed to be called successfully | before its body has been elaborated is to prevent any attempts to access | objects that do not exist. For example, suppose we modified the example in | the question so procedure R referenced object P.C: | | procedure R is | begin | P.C(1) := P.C(1) + 3; | end R; | | When Q(4) is called, P.C will not yet have been created or initialized for | this call of Q, so the body of the modified R will access a non-existent | object. Hence, the call should be prevented. The rules given in 3.9(3) are | to be understood with respect to the current elaboration of a declarative | part, and hence, the body of R is not considered to be "already elaborated" | when R is called at (1) in the question. !appendix 89-02-08 ***************************************************************************** !section 03.01 (09) M Saaltink 89-02-08 83-01260 !version 1983 !topic Reversion to not-yet-elaborated state Declarations can be elaborated more than once. For example, the declarations appearing in the declarative part of a subprogram body are elaborated each time the subprogram is called [ARM 6.3(6)]. However, [ARM 3.1(9)] states "The elaboration of any declaration always has at least the effect of achieving this change of state (from not yet elaborated to elaborated)." These two statements in conjunction imply that at some time the declarations in the declarative part of a subprogram body have their states changed from DRAFT DRAFT DRAFT Each elaboration of a declarative part is independent AI-00809/01 3 90-05-18 ra WI elaborated back to not-yet-elaborated (if the subprogram is called more than once). This does not appear to be described anywhere in the ARM and leads to some possible differences in interpretation. For example, consider this procedure: procedure Q (x: integer) is procedure R; function f return integer is begin if x = 1 then R; end if; return 0; end f; package P is c: constant integer := f; end P; procedure R is begin null; end R; begin if x < 1 then Q(1); end if; end Q; and consider the call Q(0). The declarative region of Q can be elaborated without error. Then in the recursive call Q(1), the initialization of c causes execution of f, which will call R. Now, has the declaration of the body of R been elaborated or not? In particular, will PROGRAM_ERROR be raised (by virtue of [ARM 3.9(5)])? The declaration of the body of R has indeed been elaborated before; that occurred before the recursive call Q(1). So there should be no PROGRAM_ERROR. On the other hand, after c is initialized, the declaration of the body of R will be elaborated again, and will at that time change state from not-yet-elaborated to elaborated. So perhaps when c is being initialized, the declaration of the body of R has already reverted to that not-yet-elaborated state, and there should be a PROGRAM_ERROR. [ARM 3.9(3)] suggests that the reversion to the not-yet-elaborated state should occur at the beginning of the elaboration of the declarative part containing the declaration. Now consider procedure Q2 (x: integer) is procedure R; function f return integer is begin if x = 0 then Q2(1); R; end if; return 0; end f; package P is c: constant integer := f; end P; procedure R is begin null; end R; begin null; DRAFT DRAFT DRAFT Each elaboration of a declarative part is independent AI-00809/01 4 90-05-18 ra WI end Q2; This time, in the call Q2(0), when c is being initialized there is a recursive call from f to Q2(1). In the course of that call, the declaration of the body of R is elaborated. Thus one might expect that when that call returns, the declaration of the body of R is still in this elaborated state, even when [ARM 3.9(3)] is taken into account, and so PROGRAM_ERROR should not be raised. Some validated Ada compilers do in fact raise PROGRAM_ERROR in executing these procedures. The above considerations show that the terms used in describing elaboration are ill-chosen. Since a single declaration may be elaborated many times, any reference to "the elaboration" (as a definite event) is meaningless. Thus, for example, [ARM 3.1(8,9)] and [ARM 3.9(3-8)] are not sensible. DRAFT DRAFT DRAFT