Array of pointers

Array of pointers

Hi,

I'm trying to write a subroutine in Fortran. I've got several variables and I would like to have an array with pointers to this variables. This subroutine looks pretty like this:

subroutine U_SUB(Var1, Var2, Var3)

logical, intent(inout), target :: Var1
logical, intent(inout), target :: Var2
logical, intent(inout), target :: Var3
type element
  logical, pointer, dimension(:) :: ptr
end type element

type(element), dimension(3) :: array

array(1)%ptr => Var1
array(2)%ptr => Var2
array(3)%ptr => Var3

end subroutine U_SUB

So I get this error on array(1)%ptr => Var1 and the following

The rank of the target is different from the pointer [PTR]

What is wrong? Thanks in advance.

 

 

 

5 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.
Portrait de Andrew Smith

Fortran does not have such a thing as an array of pointers. What your code gives you is a single pointer that should be pointed at an array. Therefore the compiler rightly complains when you try to point it at a scalar. Just remove "dimension(:)" for ptr.

Hey thanks for the explaining. It works now :)

Citation :

Andrew Smith a écrit :

Fortran does not have such a thing as an array of pointers. What your code gives you is a single pointer that should be pointed at an array. Therefore the compiler rightly complains when you try to point it at a scalar. Just remove "dimension(:)" for ptr.

Andrew,

Your comment is highly misleading to the readers.  What you say may have relevance to those who get deep into assembly code and compiler programming and makes comparisons with pointers in C/C++, etc. but I don't think that is of interest to Matthias and other average readers.

Your suggested change is appropriate, but the main point is that in Fortran, the type and kind parameters, and rank for the target and pointer must be the same and not that pointer and target variables cannot have array properties.  

Please refer to Fortran 2003 and/or 2008 standard documentation as well as Intel Fortran help (see excerpt below) for details on the use of pointers in Fortran:

Pointer Assignments
In ordinary assignment involving pointers, the pointer is an alias for its target.
 
In pointer assignment, the pointer is associated with a target.
 
If the target is undefined or disassociated, the pointer acquires the same status as the target.
 
Pointer assignment has the following form:
 
 
pointer-object[ (s-spec) ] =>target
 
 
pointer-object Is a variable name or structure component declared with the POINTER attribute.
 
s-spec Is a shape specification consisting of bounds information in the form "[lower-bound]:"
 
 or "[lower-bound] :upper-bound".
 
target Is a variable or expression.
Its type and kind parameters, and rank must be the same as pointer-object unless bounds
 
remapping is specified. It cannot be an array section with a vector subscript.
 
DESCRIPTION
 
If the target is a variable, it must have the POINTER or TARGET attribute,
or be a subobject whose parent object has the TARGET attribute.
 
If the target is an expression, the result must be a pointer.
 
If the target is not a pointer (it has the TARGET attribute), the pointer object
 
is associated with the target.
 
If the target is a pointer (it has the POINTER attribute), its status
 
determines the status of the pointer object, as follows:
 


If the pointer is associated, the pointer object is associated with the same object as the target




If the pointer is disassociated, the pointer object becomes disassociated


If the pointer is undefined, the pointer object becomes undefined


A pointer must not be referenced or defined unless it is associated with a
 
target that can be referenced or defined.
 
When pointer assignment occurs, any previous association between the
 
pointer object and a target is terminated.
 
Pointers can also be assigned for a pointer structure component by
 
execution of a derived-type intrinsic assignment statement
 
or a defined assignment statement.
 
Pointers can also become associated by using
 
the ALLOCATE statement to allocate the pointer.
 
Pointers can become disassociated by deallocation,
 
nullification of the pointer (using the DEALLOCATE or NULLIFY
 
statements), or by reference to the NULL intrinsic function.
 
Pointer assignment for arrays allows lower bounds to be specified.
 
The specified lower bounds can be any scalar integer expressions.
 
Remapping of the elements of a rank-one array is permitted.
 
The mapping is in array-element order and the target array
 
must be large enough.
 
The specified bounds may be any scalar integer expressions.
 
 

The following code fragment from POINTER description in Intel Fortran Help shows how to use pointers in an array context:

 REAL, POINTER :: arrow (:)
 REAL, ALLOCATABLE, TARGET :: bullseye (:,:)
 ! The following statement associates the pointer with an unused
 ! block of memory.
 ALLOCATE (arrow (1:8), STAT = ierr)
 IF (ierr.eq.0) WRITE (*,'(/1x,a)') 'ARROW allocated'
 arrow = 5.  
 WRITE (*,'(1x,8f8.0/)') arrow
 ALLOCATE (bullseye (1:8,3), STAT = ierr)
 IF (ierr.eq.0) WRITE (*,*) 'BULLSEYE allocated'
 bullseye = 1.
 bullseye (1:8:2,2) = 10.
 WRITE (*,'(1x,8f8.0)') bullseye
 ! The following association breaks the association with the first  
! target, which being unnamed and unassociated with other pointers,  
! becomes lost. ARROW acquires a new shape.
 arrow => bullseye (2:7,2)  
 WRITE (*,'(/1x,a)') 'ARROW is repointed & resized, all the 5s are lost'  
 WRITE (*,'(1x,8f8.0)') arrow
 NULLIFY (arrow)
 IF (.NOT.ASSOCIATED(arrow)) WRITE (*,'(/a/)') ' ARROW is not pointed'
 DEALLOCATE (bullseye, STAT = ierr)
 IF (ierr.eq.0) WRITE (*,*) 'Deallocation successful.'
 END
 

Portrait de Andrew Smith

A pointer to an array is fine if that is what you need. But if you need an array of pointers as mentioned by the poster then an array of derived types, each containing a pointer is the standard way of creating your own. It is a common misundertanding that a pointer to an array will do the job. But unfortunately a pointer to an array is only a single pointer to the array (or part of an array as mentioned by FortranFan).

Connectez-vous pour laisser un commentaire.