Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Parameterized derived types with pointers to same type as components

Fábio_Mallaco
Beginner
675 Views

Basically I have a derived type that represents a cell and I wanted it to have pointers to its neighbours. This is the data structure I would like to have:

module XYZ
...
    type pointerToCellContainer
        type( cellType ), pointer :: p
    end type pointerToCellContainer
...
    type cellType(nDOFs, nEQs)
        integer(itp), len :: nDOFs
        integer(isp), len :: nEQs
        ...
        type( pointerToCellContainer ), dimension(2) :: nb
        ...
    contains
        ...
    end type cellType
...
end module XYZ

While the module compiles fine when i try to atribute a cell to the pointer in the main program the compiler returns the error

main.f90(130): error #6795: The target must be of the same type and kind type parameters as the pointer.   

mesh%cellList(cID)%nb(1)%p => mesh%cellList(cID-1) ---------------------------------^ main.f90(131): error #6795: The target must be of the same type and kind type parameters as the pointer.

mesh%cellList(cID)%nb(2)%p => mesh%cellList(cID+1) ---------------------------------^

My main doubt is if I'm actually trying to do something not allowed by the 2008 standard or if it's just a syntax problem. I'm doing this code to teach myself some features that I never got to use in production code (mainly parameterized derived types, submodules and other OO features) so workarounds and alternative design solution are also welcome.

 

 

 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
675 Views

The compiler should not have allowed:

type( cellType ), pointer :: p

since cellType is parameterized and you have not specified defaults for the omitted parameters. I will report that. Issue ID is DPD200414726.

It's not clear to me what you're doing with the type parameters here. Can you explain in more detail?

0 Kudos
Fábio_Mallaco
Beginner
675 Views

First of all thanks for pointing out the missing parameters. Despite fixing that I was still having problems compiling that module so I made a little test program. The idea is to have in each cell of an unstructured mesh set of pointers to it neighbours. In this case the mesh is 1D and the structure is similar to a double linked list. I know a double linked list can be build with the derived type matList1 but this wouldn't be extensible to higher dimensions since the number of neighbours may vary so i wanted to build a vector of pointer containers.

program test
    type matList1(i,j)
        integer, len :: i,j
        type( matList1(i,j) ), pointer :: prev => null()
        type( matList1(i,j) ), pointer :: next => null()
    end type

    type pointerContainer(i,j)
        integer, len :: i,j
        type( matList2(i,j) ), pointer :: p => null()
    end type

    type matList2(i,j)
        integer, len :: i, j
        real, dimension(i,j) :: m
        type( pointerContainer(i,j) ), dimension(2) :: nb
    end type

    type( matList1(2,2) ) :: mat1
    type( matList2(2,2) ) :: mat2
end program test

This was my first try but it yielded the following error

test.f90(10): error #8724: A type parameter spec list may only appear if the type is parameterized.   
        type( matList2(i,j) ), pointer :: p => null()
-----------------------^
compilation aborted for test.f90 (code 1)

So i changed the declaration order of the pointer container and the target derived type

program test
    type matList1(i,j)
        integer, len :: i,j
        type( matList1(i,j) ), pointer :: prev => null()
        type( matList1(i,j) ), pointer :: next => null()
    end type

    type matList2(i,j)
        integer, len :: i, j
        real, dimension(i,j) :: m
        type( pointerContainer(i,j) ), dimension(2) :: nb
    end type

    type pointerContainer(i,j)
        integer, len :: i,j
        type( matList2(i,j) ), pointer :: p => null()
    end type

    type( matList1(2,2) ) :: mat1
    type( matList2(2,2) ) :: mat2
end program test

Yet another error apeared

test.f90(11): error #6457: This derived type name has not been declared.   [POINTERCONTAINER]
        type( pointerContainer(i,j) ), dimension(2) :: nb
--------------^
compilation aborted for test.f90 (code 1)

As far as I can tell there is no nice way around this and yet I can't see any reason for it not to be allowed.

PS: Using the Fortran Composer v17.0.0 and compiling without any flag, just "ifort test.f90"

0 Kudos
Steven_L_Intel1
Employee
675 Views

I'm not sure about the first error and will look into that, but the second is because the language does not allow "forward references" to a type unless the reference is POINTER or ALLOCATABLE.

0 Kudos
Steven_L_Intel1
Employee
675 Views

The first error in #3 is indeed a compiler bug. It needs to defer complaining about type parameters for a pointer or allocatable component until it has seen the type. Escalated as issue DPD200414839.

0 Kudos
Fábio_Mallaco
Beginner
675 Views

Do you have any idea of when it might get fixed? In the next major release or before/after?

0 Kudos
Steven_L_Intel1
Employee
675 Views

Most likely in an update, but it's much too soon to tell.

0 Kudos
Reply