Allocatable array elements (in user types) and pointers

Allocatable array elements (in user types) and pointers

Ritratto di Kamil Kie

I write this topic again, becouse last one was totaly wrong, example code have bugs and topic text was chaotic. I correct it, but probably nobody look on it now (http://software.intel.com/en-us/forums/topic/338043) . So  I decide to create new one - (if you are moderator or admin, please delete my previous topic, and not delete this one). 

Becouse in my calculation I use very complicated formulas, and data types, for me is extremly important to have ability to alias allocatable arrays elements. For me is alsow very important to use allocatable arrays - not other constructions. Below you have 2 codes. First one use trick and work, second don't use trick and doesn't work.

program PointerBugSol

type :: StatisticOutMeridItem_type
 character :: name*(32) 
 real, allocatable :: m(:,:)
 end type
 type :: Statistics_type 
 real :: avgValM
 type(StatisticOutMeridItem_type), allocatable :: collectStatisticsMeridItems(:) ! (CSMI)
 end type

type(Statistics_type) statistics
 type(StatisticOutMeridItem_type), pointer :: p 
 integer :: i,j,k

!---------- Initialize
allocate(statistics%collectStatisticsMeridItems(3))
 do k=1,3
 allocate(statistics%collectStatisticsMeridItems(k)%m(10,10))
 statistics%collectStatisticsMeridItems(k)%m=k+1
 print *,"values on init:",statistics%collectStatisticsMeridItems(k)%m(1,1),k
 statistics%collectStatisticsMeridItems(k)%name="test"
 end do
!------------- Run test
call ptrGet(statistics%collectStatisticsMeridItems(1),p) ! now p is alias to st%collectStatisticsMeridItems(1)
p%m=(p%m+1)*p%m + (p%m*2.1)**(p%m-1) - 3./p%m + p%m**2

call ptrGet(statistics%collectStatisticsMeridItems(2),p) ! now p is alias to st%collectStatisticsMeridItems(2)
 p%m=(p%m+1.5)*p%m + (p%m*3.1)**(p%m-1) - 4./p%m + p%m + (p%m+31)*p%m + (p%m*2.1)**(p%m-2)
!------------- Veiw results
print *,"After test:"
 do k=1,3
 print *,"values on stop:",statistics%collectStatisticsMeridItems(k)%m(1,1),k
 end do

contains

subroutine ptrGet(el,r)
 type(StatisticOutMeridItem_type), target :: el
 type(StatisticOutMeridItem_type), pointer :: r
 r => el
 end subroutine

end program

Second code:

program PointerBugSol

type :: StatisticOutMeridItem_type
 character :: name*(32) 
 real, allocatable :: m(:,:)
 end type
type :: Statistics_type 
 real :: avgValM
 type(StatisticOutMeridItem_type), allocatable, target :: collectStatisticsMeridItems(:) ! (CSMI)
 end type

type(Statistics_type) statistics
 type(StatisticOutMeridItem_type), pointer :: p 
 integer :: i,j,k

!---------- Initialize
allocate(statistics%collectStatisticsMeridItems(3))
 do k=1,3
 allocate(statistics%collectStatisticsMeridItems(k)%m(10,10))
 statistics%collectStatisticsMeridItems(k)%m=k+1
 print *,"values on init:",statistics%collectStatisticsMeridItems(k)%m(1,1),k
 statistics%collectStatisticsMeridItems(k)%name="test"
 end do
!------------- Run test
p=>statistics%collectStatisticsMeridItems(1) 
 p%m=(p%m+1)*p%m + (p%m*2.1)**(p%m-1) - 3./p%m + p%m**2
p=>statistics%collectStatisticsMeridItems(2) 
 p%m=(p%m+1.5)*p%m + (p%m*3.1)**(p%m-1) - 4./p%m + p%m + (p%m+31)*p%m + (p%m*2.1)**(p%m-2)
!------- Show results
 print *,"After test:"
 do k=1,3
 print *,"values on stop:",statistics%collectStatisticsMeridItems(k)%m(1,1),k
 end do

end program

I use ifort 12.0.4 , for compilation and for run I type following line:

ifort PointerBugSol.f90

a.out

Here is compilation message:

PointerBug1.f90(32): error #6796: The variable must have the TARGET attribute or be a subobject of an object with the TARGET attribute, or it must have the POINTER attribute. [STATISTICS]
p=>statistics%collectStatisticsMeridItems(2)


The differences is that in line 09 in second code attrib "target" appear, and in first code we use tricky function "ptrGet" (ilnes 25 and 28). In second code we use direct way to get pointer (lines 25 and 27)

Why first code works, but second code don't ? There exist non-tricky , direct way, to get pointer to allocatable array element in user define type?

3 post / 0 new
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione
Ritratto di Kamil Kie

One person give me answer:

"change type(Statistics_type) statistics to type(Statistics_type), target::statistics"

It works, and now everything is clear. I have deadlock in my head - I don't see it.

However there is some back door in ifort which allow to skip word "target" and use subroutine (ptrGet) ...

Ritratto di Steve Lionel (Intel)

I think you got some good answers in the other thread. You should not be looking for "tricky, indirect, back door" methods and instead stick to what the standard provides.

Steve

Accedere per lasciare un commento.