J3/00-324
Date: 25 November 2000
To: J3
From: Van Snyder
Subject: Amendment to "Request for Interpretation of `prior
specification'"
References: 00-229
NUMBER: ?
TITLE: What do ``Prior Specification'' and ``defined previously'' mean?
KEYWORDS: prior Specification, defined previously
DEFECT TYPE: Clarification
STATUS: J3 consideration in progress
QUESTION
What is a ``prior specification?''
The last normative paragraph of section 7.1.6.1 of the Fortran 95
standard, immediately before note 7.14 [94:38-41 in 97-007r2] states:
``If an initialization expression includes a reference to an inquiry
function for a type parameter or an array bound of an object specified in
the same , the type parameter or array bound shall be
specified in a prior specification of the . The
prior specification may be to the left of the inquiry function in the
same statement.''
The first two sentences of the last normative paragraph of section
7.1.6.2 of the Fortran 95 standard, immediately before note 7.16
[96:32-35 in 97-007r2] are similar, but refer to specification
expressions.
Unfortunately, there is no definition of ``prior specification.''
Consider:
1. INTEGER :: P(complicated_expression_for_lower_bound_1: &
& complicated_expression_for_upper_bound_1, &
& complicated_expression_for_lower_bound_2: &
& complicated_expression_for_upper_bound_2) = &
& RESHAPE( (/ 11, 21, 12, 22 /), SHAPE(P) )
(Notice the reference to P in the .)
Some processors reason ``the `specification' of P is only the specifica-
tion of its name, kind, rank and array bounds, and therefore is `prior'
by the time the is encountered,'' and accept this.
Others reason ``the `specification' of P is the syntax term
defined by syntax rule R504 on page 47, which includes the , and it is therefore not `prior' until the is
completely specified,'' and do not accept this.
By way of further examples, which of the following are standard
conforming?
2. INTEGER(selected_int_kind(4)) :: A(KIND(A))
3. INTEGER :: A(2,2*SIZE(A,1)+1)
4. CHARACTER :: C(10)*(SIZE(C,1))
5. INTEGER :: P(10) = LBOUND(P,1)
The paragraphs cited above are silent concerning inquiry functions that
are not for type parameters or array bounds. These include BIT_SIZE,
DIGITS, EPSILON, MAXEXPONENT, MINEXPONENT, PRECISION, RADIX, RANGE and
TINY. The results of all of these are derived, however, from the types
and kind type parameters of their arguments.
Are the objects about which these functions inquire required to be
specified in a prior specification of the , and is
that specification allowed to be in the same statement so long as it is
to the left of the inquiry function of which it is an argument?
Which of the following are standard conforming?
6: INTEGER :: B = BIT_SIZE(B)
7. INTEGER :: B(BIT_SIZE(B))
8. INTEGER :: D = DIGITS(D)
9. INTEGER :: D(DIGITS(D))
10. REAL :: X = EPSILON(X)
One could construct obvious similar examples for the remainder of inquiry
functions that do not inquire about type parameters or array bounds.
RELATED QUESTION
The second normative paragraph in subclause 5.1.2.1 [52:27-28 in
97-007r2] states ``Any named constant that appears in the initialization
expression shall have been defined previously in the same type
declaration statement....'' The third normative paragraph after syntax
rule R531 in subclause 5.2.9 [61:4-7 in 97-007r2] is similar.
Does ``defined previously'' mean that all of the properties of the named
constant shall have been defined previously, or that a referenced
property of it shall have been defined previously? E.g. if the KIND is
needed, is it necessary for the value to have been defined?
PREFERRED ANSWER(S)
The result of an inquiry function that depends on the type and type
parameters (e.g. DIGITS) of its argument can be referenced if the
argument has appeared in a context that specifies the type and type
parameters. This makes examples 1 and 6-10 standard-conforming. A bound
may be referenced as soon as it is defined. This makes examples 2-5
standard-conforming. Examples 5, 6, 8 and 10 remain standard-conforming
if the PARAMETER attribute is specified. If allowing example 3 is too
difficult, the second rule could be relaxed to ``a bound cannot be
referenced until all of the bounds are defined.'' If a property of an
entity has been inquired about, it cannot later be respecified. The
value of an object can be referenced only after that object is completely
specified.
Note that
11. CHARACTER(len=*), PARAMETER :: P(len(P)) = (/ ('abc', i=1,len(P)) /)
12. CHARACTER(len=9) :: C(len(C))*(20)
14. INTEGER, PARAMETER :: P(P(3)) = (/ 1, 2, 4, 8 /)
would not become standard-conforming.
If all four of these rules are too difficult to implement, it would at
least be useful if ``prior specification'' referred only to a prior
, but without including the part; the
utility of this interpretation is illustrated most vividly by example 1.
The presence of the word ``completely'' in the last sentence of the last
normative paragraph of 7.1.6.2, and its absence elsewhere, indicates that
this was the intent: ``If a specification function includes a reference
to a value of an array element of an array specified in the same
, the array shall be completely specified in prior
specifications.''
Unfortunately, there is at present no syntax term to which to direct this
kind of reference.
The type and kind type parameters are completely specified by the
. Since the cited paragraphs refer to ``specification'' but
not to a syntax term, and the inquiry functions BIT_SIZE etc. mentioned
above depend on the type and kind type parameters, it is reasonable to
interpret examples 2, 7 and 9 to be standard-conforming.
REMARK
There is at least one Fortran 95 processor that accepts
program test
INTEGER :: P(2,2) = &
& RESHAPE( (/ 11, 21, 12, 22 /), SHAPE(P) )
INTEGER(selected_int_kind(4)) :: A(KIND(A))
INTEGER :: B(2,2*SIZE(B,1)+1)
CHARACTER :: C(10)*(SIZE(C,1))
INTEGER :: D(10) = LBOUND(D,1)
INTEGER :: E = BIT_SIZE(E)
INTEGER :: G(BIT_SIZE(G))
INTEGER :: H = DIGITS(H)
INTEGER :: I(DIGITS(I))
REAL :: X = EPSILON(X)
INTEGER, PARAMETER :: PP(2,2) = &
& RESHAPE( (/ 11, 21, 12, 22 /), SHAPE(PP) )
INTEGER, PARAMETER :: DP(10) = LBOUND(DP,1)
INTEGER, PARAMETER :: EP = BIT_SIZE(EP)
INTEGER, PARAMETER :: HP = DIGITS(HP)
REAL, PARAMETER :: XP = EPSILON(XP)
print *, 'P(1,1), P(1,2), P(2,1), P(2,2) =', p(1,1), p(1,2), p(2,1),
p(2,2)
print *, 'size(A) =', size(a), ', kind(A) =', kind(a)
print *, 'shape(B) =', shape(b)
print *, 'len(C) =', len(c), ', size(c,1) =', size(c,1)
print *, 'D(1) =', d(1), ', lbound(d,1) =', lbound(d,1)
print *, 'E =', e, ', bit_size(E) =', bit_size(e)
print *, 'size(G) =', size(g), ', bit_size(G) =', bit_size(g)
print *, 'H =', h, ', digits(H) =', digits(h)
print *, 'size(I) =', size(i), ', digits(I) =', digits(i)
print *, 'X =', x, ', epsilon(X) =', epsilon(x)
print *, 'Parameter == non-parameter = ', &
& all(p == pp) .and. all(d == dp) .and. e == ep .and. h == hp .and. x ==
xp
end program test
Its output is:
P(1,1), P(1,2), P(2,1), P(2,2) = 11 12 21 22
size(A) = 2 , kind(A) = 2
shape(B) = 2 5
len(C) = 10 , size(c,1) = 10
D(1) = 1 , lbound(d,1) = 1
E = 32 , bit_size(E) = 32
size(G) = 32 , bit_size(G) = 32
H = 31 , digits(H) = 31
size(I) = 31 , digits(I) = 31
X = 1.19209290E-07 , epsilon(X) = 1.19209290E-07
Parameter == non-parameter = T
If the bounds of B are changed to B(2,2*SIZE(B,2)+1) the program is
rejected.
SUBMITTED BY: Van Snyder
HISTORY: 00-229 m154 Submitted
00-324 m155 Amended