[Patch, fortran] PR29422 and PR29428 - allocatable component wrinkles

Brooks Moses bmoses@stanford.edu
Wed Oct 11 21:03:00 GMT 2006


Dominique Dhumieres wrote:
>>Dominique d'Humieres has pointed out to me that the arrays need to be
>>normalised so that lbound is one, rather than for example, copying the
>>array bounds of constructor elements.
> 
> More precisely I have pointed out that g95 normalize the array bounds of 
> constructor elements, as shown by the following example (derived from 
> alloc_comp_constructor_1.f90):

Or, simpler version that produces the key result:

Program test_constructor
     implicit none
     type :: mytype
	integer, allocatable :: a(:)
     end type mytype
     integer :: y(-1:0) = 0
     type (mytype) :: x

     x = mytype(y)
     if (.not.allocated(x%a)) call abort()
     print *, 'y bounds'
     print *, lbound(y)
     print *, ubound(y)
     print *, 'x%a bounds'
     print *, lbound(x%a)
     print *, ubound(x%a)
end program test_constructor

>>This is a rather substantial change, since it will hit various testcases
>>too.  I will not hurry to fix this because we have survived until the 9th
>>of this month with incorrectly normalised bounds all over the place
>>(PR29391).  However, I will try to get it sorted on the timescale of a
>>week.
> 
> I think before doing "substantial change", I would suggest to ask those 
> supposed to know the "standard conforming" behavior which one is right.
> Does the "otherwise 1" in the definition of LBOUND() applies to this 
> situation?

It does not apply; x%a is a whole array, with dimensions of nonzero 
extent -- nothing complicated at all.  The Fortran 95 standard is poorly 
written here (and I think may say the negative of what it means, or at 
least could be read that way); the F2003 standard is rather better.

The real question is what happens in the constructor.

And, looking at section 4.5.9 of the Fortran 2003 standard, I think the 
following paragraph is most relevant:

> If a component of a derived type is allocatable, the corresponding 
> constructor expression shall either be a reference to the intrinsic 
> function NULL with no arguments, an allocatable entity of the same rank,
> or shall evaluate to an entity of the same rank. If the expression is a 
> reference to the intrinsic function NULL, the corresponding component of 
> the constructor has a status of unallocated. If the expression is an 
> allocatable entity, the corresponding component of the constructor has 
> the same allocation status  as that allocatable entity and, if it is 
> allocated, the same dynamic type, bounds, and value; if a length  
> parameter of the component is deferred, its value is the same as the 
> corresponding parameter of the expression. Otherwise the corresponding 
> component of the constructor has an allocation status of allocated and 
> has the same bounds and value as the expression.

Here, y evaluates "to an entity of the same rank", and the x%a "has the 
same bounds and value as the expression."

So, there's a rather interesting question -- what are the bounds of y, 
when it's viewed as an expression?

Honestly, I'm having a hard time coming up with an answer.  Section 
7.1.4.1 would appear to be the relevant section to start with; it states 
that if an expression is a primary (which this is), and the primary is a 
variable (which this is), then the "shape" of the expression is that of 
the variable.  Unfortunately, this doesn't really answer the question; 
2.4.5 makes it clear that "shape" is the extents of the array, not the 
bounds.

Thus, the standard does not, as far as I can tell, state what the lower 
bounds of x%a should be.  I can see two arguments:

1.) The lower bound is not specified; thus, it should be 1.

2.) In the absence of explicit commentary to the contrary, this should 
be equivalent to x%a = y (for an unallocated x%a), and there 7.4.1.3 is 
quite clear that the lower bound of x%a should be equal to LBOUND(y).

Regrettably, these two arguments produce different answers; I think I'll 
post this on comp.lang.fortran and see what it gets there.

(Personally, I prefer the second answer -- which is what gfortran 
currently does.)

- Brooks



More information about the Fortran mailing list