Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Type specification and initialization expressions

10 views
Skip to first unread message

Tobias Burnus

unread,
Jan 31, 2008, 7:38:34 AM1/31/08
to
Hello,

Is the following code valid or not?

implicit none
REAL(kind(0.0d0)), dimension(kind(xyz)) :: xyz
REAL, PARAMETER :: xxx(kind(xxx)) = 1.0

This is accepted by NAG f95 and gfortran (and both have then size(xyz)
== kind(0d0)), but it is unclear for me whether this is valid.

For the following I am rather sure that it is valid:
REAL, DIMENSION(2,2), PARAMETER :: xyz2 = RESHAPE((/ 1,2,3,4 /),
SHAPE(xyz2))
REAL, PARAMETER :: yyy = kind(yyy)

while the following should be invalid:
REAL(8), PARAMETER :: zzz(size(zzz)) = 1 ! Obviously - which
dimension one should get?
real, parameter :: z = transfer(1234, z)

My starting point was "7.1.7 Initialization expression" (esp. last
paragraph).

Tobias

James Giles

unread,
Jan 31, 2008, 3:37:46 PM1/31/08
to
Tobias Burnus wrote:
> Hello,
>
> Is the following code valid or not?
>
> implicit none
> REAL(kind(0.0d0)), dimension(kind(xyz)) :: xyz
> REAL, PARAMETER :: xxx(kind(xxx)) = 1.0
>
> This is accepted by NAG f95 and gfortran (and both have then size(xyz)
> == kind(0d0)), but it is unclear for me whether this is valid.

I don't think it is since KIND(xyz) is not defined until after xyz is
declared. I don't think *during* the declaration counts as *after*.
The following has been discussed before and I think was determined
to be non-standard for the same reason:

Real :: X(5), Y(size(x))

Even if such things were standard, I would avoid then for legibility
reassons.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


Steve Lionel

unread,
Jan 31, 2008, 4:23:35 PM1/31/08
to
On Jan 31, 7:38 am, Tobias Burnus <bur...@net-b.de> wrote:
> Hello,
>
> Is the following code valid or not?
>
> implicit none
> REAL(kind(0.0d0)), dimension(kind(xyz)) :: xyz
> REAL, PARAMETER :: xxx(kind(xxx)) = 1.0

We've been here before. Here's the text of Interp 00090 against F95
discussing this issue. The text was clarified in F2003. I'll comment
for the record that Intel Fortran doesn't get all the cases right
either in that we accept and do not warn about certain non-standard
usages. We intend to fix that in a future release.

Steve

NUMBER: 000090
TITLE: What do ``Prior Specification'' and ``defined previously''
mean?
KEYWORDS: initialization, prior specification, defined previously
DEFECT TYPE: Erratum
STATUS: Included in corrigendum/complete

QUESTION 1

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 <specification-part>, the type parameter or array bound
shall be specified in a prior specification of the <specification-
part>. 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 <initialization>.)

Some processors reason ``the `specification' of P is only the
specification of its name, kind, rank and array bounds, and therefore
is `prior' by the time the <initialization> is encountered,'' and
accept this.

Others reason ``the `specification' of P is the syntax term <entity-
decl> defined by syntax rule R504 on page 47, which includes the
<initialization>, and it is therefore not `prior' until the
<initialization> 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 <specification-part>, 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.

QUESTION 2

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?

ANSWER 1

A prior specification refers to a specification in a previous
<entity-decl> or in a previous statement. None of the examples
are legal. Edits are included to clarify this.

ANSWER 2

In the referenced text (5.1.2.1), "Any named constant that
appears ... shall have been defined previously" mean that all of
the properties of the named constant shall have been defined
previously; therefore, if the KIND of a named constant is
needed, is it necessary for the value of that named constant to
have been defined previously also.

EDITS:

Page 94, Subclause 7.1.6.1. In the first line of the last
paragraph of page 94 [94:38], replace 'for a type parameter' by
'that depends on a type parameter'.

Page 94, Subclause 7.1.6.1, replace the last sentence of page
94 [94:40-41] by 'The prior specification may be to the left of
the inquiry function in the same statement, but shall not be
within the same <entity-decl>.'

Page 96, Subclause 7.1.6.2. In the first line of the last
paragraph of the subclause [96:32], replace 'for a type
parameter' by 'that depends on a type parameter'.

Page 96, Subclause 7.1.6.2, replace the second sentence of the
last paragraph of the subclause [96:34-35] by 'The prior
specification may be to the left of the inquiry function in the
same statement, but shall not be within the same
<entity-decl>.'

SUBMITTED BY: Van Snyder

HISTORY: 00-229 m154 Submitted
00-324 m155 Amended
01-138r1 m156 Passed by J3 meeting
01-224r1 m157 Passed by J3 letter ballot
WG5/N1451 Passed by WG5 ballot

James Giles

unread,
Jan 31, 2008, 4:41:33 PM1/31/08
to
James Giles wrote:
...

> The following has been discussed before and I think was determined
> to be non-standard for the same reason:
>
> Real :: X(5), Y(size(x))

By Steve's response it's clear that I mis-remembered the case.
The one that I recalled must have been something like:

Real :: X(4) = size(X)

I still stand by the observation:

> Even if such things were standard, I would avoid then for legibility

> reasons.

Tobias Burnus

unread,
Feb 1, 2008, 4:55:41 AM2/1/08
to
On Jan 31, 10:23 pm, Steve Lionel <steve.lio...@intel.com> wrote:
> On Jan 31, 7:38 am, Tobias Burnus <bur...@net-b.de> wrote:
> > Is the following code valid or not?
[...]

> We've been here before. Here's the text of Interp 00090 against F95
> discussing this issue. The text was clarified in F2003.

Thanks for the pointer. Then I initially read the standard correctly
but as all compilers allowed more - even those regarded as picky, I
thought that I misread the standard and tried to make sense of of it
- with little success.

> I'll comment for the record that Intel Fortran doesn't get all the cases
> right either in that we accept and do not warn about certain non-standard
> usages. We intend to fix that in a future release.

Ditto for gfortran.


On Jan 31, 10:41 pm, "James Giles" <jamesgi...@worldnet.att.net>
wrote:


> James Giles wrote:
> I still stand by the observation:
> > Even if such things were standard, I would avoid then for legibility
> > reasons.

Well, my question was motivated by deciding whether gfortran needs to
be fixed (for -std=f95/f2003 at least). I did and do not intent to use
such constructs.


Although I have to admit that I find things like the following rather
convenient:

real :: a(1,1,1,2) = reshape( [1.0, 2.0], shape(a) )

Thanks again Steve and James!

Tobias

James Giles

unread,
Feb 1, 2008, 1:43:20 PM2/1/08
to
Tobias Burnus wrote:
...

> Although I have to admit that I find things like the following rather
> convenient:
>
> real :: a(1,1,1,2) = reshape( [1.0, 2.0], shape(a) )

Yes it is irritating that it doesn't work. It's a peculiar
asymmetry that [ARRAY] is valid regardless of the rank
of ARRAY, but ARRAY = [anything] is not valid if
ARRAY is not rank 1. I think that array constructors
should interoperate with arrays of any rank provided
the size is correct. Elements line up in array element
order, of course.

0 new messages