Error: the name of the part to the right of the part-ref with non-zero rank has the ALLOCATABLE attribute

I would like to access the elements of an array in a massive derived type using the subroutine sum_real. That is: summation over the first record in weight for all people.

type my_type
   real, dimension(:), allocatable :: weight
   real :: total_weight
end type my_type

type (my_type), dimension (:), allocatable :: people
type (my_type) :: answer

allocate (people (2))
allocate (people (1)%weight(2))
allocate (people (2)%weight(2))

people (1) % weight(1) = 1
people (2) % weight(1) = 1
people (1) % weight(2) = 3
people (2) % weight(2) = 3

call sum_real ( people (:) % weight(1), answer % total_weight )

      

What I want to do is similar to the answer found in Derived Type Array: Select Entry , except for the fact that I have a dedicated array in a massively derived type instead of a single element.

But I am getting compiler error:

error #7828: The part-name to the right of a part-ref with nonzero rank has the ALLOCATABLE attribute (6.1.2).   [WEIGHT]

      

+3


source to share


2 answers


What you are trying to do is not possible if your component is selected. The link ( 6.1.2

) is actually a link to the official standard documents that prohibit this.

The reason is simple: the distributed components (scalar or arrays) are stored in a different part of memory than the derived type itself. Therefore, if you write

sum(people%total_weight)

      

or

people%total_weight = 0

      

this is not a problem, total_weight

it is not allocated, it is stored in the derived type and the compiler just goes into a simple loop and sets one field after another to zero. You can find out the address of each in advance %totalweight

.

On the other hand,

sum(people%weight)

      



or

people%weight = 0

      

each %weight

is stored in a different location, and you don't have a simple formula to figure out where each is %weight(i)

.

The solution is to either fix the size of the array if possible

real, dimension(2) :: weight

      

or use a do loop

s = 0
do i = 1, size(people)
  S = S + sum(people(i)%weight)
end do

      

+3


source


If you have an F2003 compiler and the component array bounds are the same for a particular parent array object, a third approach to constant expression size / using the do loop methods specified by VladimirF is to parameterize the type.

type my_type(n)        ! This type has one parameter - n
  integer, len :: n    ! The parameter n is a length parameter.
  real :: weight(n)    ! This component depends on that parameter.
end type my_type

type (my_type(:)), dimension(:), allocatable :: people

! This integer is the size of the people component.  Because 
! people is allocatable it can be determined at runtime.
number_of_people = 2

! This integer is the size of the weight component that we want 
! in the array people.  Other arrays and scalars of type 
! my_type can have different sizes for that component.  
! Because people is allocatable this can be determined at 
! runtime.
number_of_weights = 2

allocate( my_type(number_of_weights) :: people(number_of_people) )

! Define people%weight here.
people(1)%weight(1) = 1
...

! Using sum intrinsic for the sake of example
do i = 1, people%n
  ! The argument to sum is an array section.
  print *, sum(people%weight(i))
  !                 ^        ^ Reference to an element of a component
  !                 | Reference to the entire people array
end do

      

Each element of an array of a parameterized type has the same type parameters, so each component weight

in people

has the same bounds, so references such as people%weight

become "regular".



Code using this approach (or the constant component sizing approach) must still follow the constraint on component references that only one part of the reference can have a nonzero rank (you cannot work with people%weight

as a whole, since both humans and weighted component have rank one).

In the case of a distributed component, some components in some elements may not be highlighted and where they are highlighted, the component may have different borders, which makes a "regular" reference to data in the component by array elements conceptually difficult.

+4


source







All Articles