DIVISOR, STEP : POSITIVE := 5;
is a multiple declaration that declares two variables of subtype POSITIVE which are initialized with the value of the literal 5. A large number of multiple declarations are of the above form: the initial value is given by a literal or by a pure expression that delivers the same value each time it is evaluated. But consider now the multiple declaration:
YESTERDAY, TODAY, TOMORROW : DAY := GET_NEXT_DAY;
where the function GET_NEXT_DAY returns a different day each time it is called. Then there are two possible interpretations. One of them would be equivalent to:
some_day : constant DAY := GET_NEXT_DAY; YESTERDAY : DAY := some_day; TODAY : DAY := some_day; TOMORROW : DAY := some_day;
in which case all three variables would have the same value, obtained by the single evaluation of the function. However, the semantics selected for Ada is different. In fact the multiple declaration is equivalent to the following sequence of single declarations:
YESTERDAY : DAY := GET_NEXT_DAY; TODAY : DAY := GET_NEXT_DAY; TOMORROW : DAY := GET_NEXT_DAY;
in this order. This means that the function will be called three times and the variables will therefore be given three successive day values, as one expects in the present example.
Clearly, the two semantics do not differ when the initialization always yields the same value (the most frequent case). However we have found that when multiple evaluations yield different values, the most natural semantics is almost always the one involving multiple evaluations - hence the choice for Ada. Other examples are:
JOHN, PAUL : PERSON_NAME := new PERSON;
where we certainly want to allocate two new persons, and similarly:
FIRST, SECOND : constant STRING := GET_NEW_TEXT;
In this last example these two constants may have different values, and they need not even have the same length. Thus FIRST and SECOND need not even be of the same subtype of the type STRING. The same situation would also arise with
A, B : STRING(1 .. F) := (others => "*");
if F were a function and the two implied calls of F delivered different values.
In later chapters, when we discuss default expressions for record components and for parameters, we will see that the Ada semantics requires dynamic evaluation of these default expressions - as the need arises; this is quite consistent with the semantics of multiple evaluation selected for multiple declarations.