Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29280 Discussions

Problem With A Subroutine With Class and Pointer attribute

ScottBoyce
Novice
1,138 Views

I have a larger program that passes a data type into a deallocation subroutine that is a pointer, but the compilation fails saying the data type does not match.

Here is a simplified version of the code:

[fortran]

      MODULE DATATYPE

      TYPE EX1

          INTEGER,DIMENSION(:),ALLOCATABLE:: A

      END TYPE

      !

      TYPE, EXTENDS(EX1)::EX

          INTEGER:: B

      END TYPE

      !

      CONTAINS

      !

      SUBROUTINE SUB(STRUCT)

      CLASS(EX1),POINTER:: STRUCT

      !

      SELECT TYPE(STRUCT)

      TYPE IS (EX)

          DEALLOCATE(STRUCT)

      END SELECT

      !

      END SUBROUTINE

      END MODULE

      

      PROGRAM MAIN

      USE DATATYPE

      TYPE(EX),POINTER:: STRUCT

      !

      ALLOCATE(STRUCT)

      CALL SUB(STRUCT)

 

      END PROGRAM

[/fortran]

The compiler error I get is:

Error    1     error #6633: The type of the actual argument differs from the type of the dummy argument.   [STRUCT]   

 

The code works fine if I drop the POINTER attribute where I say CLASS(EX1),POINTER:: STRUCT

Is this a compiler error or is there no way to have the POINTER attribute with CLASS.

 

Thanks in advance as always!

0 Kudos
5 Replies
Steven_L_Intel1
Employee
1,138 Views

You don't get that error with this code (ignoring the misspelling of the type name.) I can tell you that this "simplified" version has a fundamental error in the SELECT TYPE construct in that, inside the construct, STRUCT does not have the ALLOCATABLE attribute. It's effectively a new variable with some, but not all, of the attributes of the same-named variable in the outer scope.

Now if you'll show me actual code that gets the error you describe, I can help with that.

0 Kudos
ScottBoyce
Novice
1,138 Views

Should I be able to deallocate STRUCT because it is a POINTER that is allocated outside of the subroutine (line 27).

 

Also when I first wrote that simplied code I did not have the deallocate statement, I just had a WRITE(*,*)' OK' on line 17. Really my problem is that the code does not like the POINTER attribute on line 13 even though STRUCT is a pointer variable.

 

I will inquire with my boss if I can distribute the original code and add back in where I was getting the error.

0 Kudos
Steven_L_Intel1
Employee
1,138 Views

There's no problem with line 13 when I try the code you posted. Can you modify that to reproduce the actual problem you're having? Be sure to actually try it with the compiler and show the actual and complete error message. Also tell me which compiler version you're using.

You can deallocate a pointer anywhere you like, as long as the pointer points to "the whole of the object that was allocated", with some restrictions. For example, you can't deallocate a pointer if its target (or any subobject thereof) is argument-associated with a dummy argument or construct associated with an associate name.

You have an additional problem in the posted code in that the dummy argument in SUB is polymorphic and a pointer, but in the main program, STRUCT is not polymorphic. The compiler says:

error #8300: If a dummy argument is allocatable or a pointer, and the dummy or its associated actual argument is polymorphic, both dummy and actual must be polymorphic with the same declared type or both must be unlimited polymorphic.   [STRUCT]

0 Kudos
ScottBoyce
Novice
1,138 Views

Thanks for your help, I was able to fix the problem by declaring STRUCT in PROGRAM MAIN as a CLASS and allocating it for the extended data type.  I believe the version of the compiler I have is Composer XE 2013 Update 3 for windows 2013.1.3.202

 

First let me show a simpler code where I get the error.

[fortran]

      MODULE DATATYPE

      TYPE EX1

          INTEGER,DIMENSION(:),ALLOCATABLE:: A

      !

      END TYPE

      TYPE, EXTENDS(EX1)::EX

          INTEGER:: B

      END TYPE

      !

      CONTAINS

      SUBROUTINE SUB(STRUCT)

      CLASS(EX1),POINTER:: STRUCT

      !

      RETURN

      !

      END SUBROUTINE

      END MODULE

 

      PROGRAM MAIN

      USE DATATYPE

      TYPE(EX),POINTER:: STRUCT

      !

      ALLOCATE(STRUCT)

      CALL SUB(STRUCT)

      END PROGRAM

[/fortran]

 

 

Now if I remove the pointer attribute on line 12, the code compiles fine.

 

[fortran]

      MODULE DATATYPE

      TYPE EX1

          INTEGER,DIMENSION(:),ALLOCATABLE:: A

      !

      END TYPE

      TYPE, EXTENDS(EX1)::EX

          INTEGER:: B

      END TYPE

      !

      CONTAINS

      SUBROUTINE SUB(STRUCT)

      CLASS(EX1):: STRUCT

      !

      RETURN

      !

      END SUBROUTINE

      END MODULE

 

      PROGRAM MAIN

      USE DATATYPE

      TYPE(EX),POINTER:: STRUCT

      !

      ALLOCATE(STRUCT)

      CALL SUB(STRUCT)

      END PROGRAM

[/fortran]

 

This is code that fixed the problem:

 

[fortran]

      MODULE DATATYPE

      TYPE EX1

          INTEGER,DIMENSION(:),ALLOCATABLE:: A

      !

      END TYPE

      TYPE, EXTENDS(EX1)::EX

          INTEGER:: B

      END TYPE

      !

      CONTAINS

      SUBROUTINE SUB(STRUCT)

      CLASS(EX1),POINTER:: STRUCT

      !

      RETURN

      !

      END SUBROUTINE

      END MODULE

 

      PROGRAM MAIN

      USE DATATYPE

      CLASS(EX1),POINTER:: STRUCT

      !

      ALLOCATE(EX::STRUCT)

      CALL SUB(STRUCT)

      END PROGRAM

[/fortran]

 

I take it there is no way to do the code as was done in the first example? (The reason I ask if I will have to make some significant changes to codes outside of my subroutines in order to get my deallocation routines to work. I already have a work around, but I rather have everything be in a single subroutine).

Thanks.

0 Kudos
Steven_L_Intel1
Employee
1,138 Views

Yes, your solution is the way to do it. The rules for type matching of pointer dummy arguments are more restrictive than for non-pointer dummy arguments - the declared types have to be the same. In your example, the declared type of the dummy is EX1, but that of the actual argument is EX. 

0 Kudos
Reply