Problem With A Subroutine With Class and Pointer attribute

Problem With A Subroutine With Class and Pointer attribute

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:

      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

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!

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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.

Steve - Intel Developer Support

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.

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]

Steve - Intel Developer Support

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.

      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

 

 

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

 

      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

 

This is code that fixed the problem:

 

      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

 

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.

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. 

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today