Enlil Maratovich
Enlil Maratovich

Reputation: 59

Puting derived types with procedures from module to submodule

I need a little help about using submodules. My intention is to use one submodule for specific derived type from parent module and I want to put the whole declaration of the derived type into the submodule. For example, this is my example code which I want to transform:

MODULE PARENT_MODULE

IMPLICIT NONE

TYPE , PUBLIC :: DERIVED_TYPE_A

  PRIVATE

  INTEGER :: I_00

  CONTAINS

  PROCEDURE , PUBLIC :: CALC_I_00 => CALC_DATA_I_00
  PROCEDURE , PUBLIC :: TAKE_I_00 => TAKE_DATA_I_00

END TYPE DERIVED_TYPE_A

PRIVATE :: CALC_DATA_I_00
PRIVATE :: TAKE_DATA_I_00

INTERFACE

  MODULE SUBROUTINE CALC_DATA_I_00( THIS , NUM_00 )

    CLASS( DERIVED_TYPE_A ) :: THIS
    INTEGER , INTENT( IN ) :: NUM_00

  END SUBROUTINE CALC_DATA_I_00

  MODULE FUNCTION TAKE_DATA_I_00( THIS ) RESULT( RES )

    CLASS( DERIVED_TYPE_A ) :: THIS
    INTEGER :: RES

  END FUNCTION TAKE_DATA_I_00

END INTERFACE

END MODULE PARENT_MODULE

SUBMODULE( PARENT_MODULE ) TYPE_A

CONTAINS

MODULE PROCEDURE CALC_DATA_I_00

  THIS%I_00 = NUM_00 + 2

END PROCEDURE CALC_DATA_I_00

MODULE PROCEDURE TAKE_DATA_I_00

  RES = THIS%I_00

END PROCEDURE TAKE_DATA_I_00

END SUBMODULE TYPE_A

PROGRAM TYPE_SUBMODULES

USE , NON_INTRINSIC :: PARENT_MODULE

IMPLICIT NONE

INTEGER :: I

CLASS( DERIVED_TYPE_A) , POINTER :: P_ARR_INT
TYPE( DERIVED_TYPE_A ) , DIMENSION( 3 ) , TARGET :: ARR_INT

D00: DO I = 1 , 3

        P_ARR_INT => ARR_INT( I )

        CALL P_ARR_INT%CALC_I_00( I )

        WRITE( * , * ) ARR_INT( I )%TAKE_I_00()

     END DO D00

END PROGRAM TYPE_SUBMODULES

Is there way for using a derived type(with components and procedures) in a submodule? For example, in this way:

SUBMODULE( PARENT_MODULE ) TYPE_A

  TYPE :: D_TYPE_A

    INTEGER :: I_00

    CONTAINS

  !  PROCEDURE :: CALC_I_00 => CALC_DATA_I_00
  !  PROCEDURE :: TAKE_I_00 => TAKE_DATA_I_00

  END TYPE D_TYPE_A

  CLASS( D_TYPE_A ) , POINTER :: P_ARR_INT
  TYPE( DERIVED_TYPE_A ) , DIMENSION( 3 ) , TARGET :: ARR_INT

CONTAINS

!MODULE SUBROUTINE CALC_DATA_I_00( THIS )
!
!    CLASS( D_TYPE_A ) :: THIS
!   ! INTEGER , INTENT( IN ) :: NUM_00
!
!    THIS%I_00 = NUM_00 + 1
!
!END SUBROUTINE CALC_DATA_I_00
!
!!FUNCTION TAKE_DATA_I_00( THIS ) RESULT( RES_00 )
!!
!!    CLASS( D_TYPE_A ) :: THIS
!!    INTEGER :: RES_00
!!
!!    RES_00 = THIS%I_00
!!
!!END FUNCTION TAKE_DATA_I_00

END SUBMODULE TYPE_A

In this case I can not use pointer and target variable in main program and I want to do that or if it is possible to make declaration of pointer and target variable in PARENT_MODULE.

My IDE is Code::Blocks 17.12 with Gfortran compiler. The version of compiler is: MinGW 6.3.0.

Upvotes: 1

Views: 1079

Answers (1)

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8546

Is there way for using a derived type(with components and procedures) in a submodule?

Short answer: no. (At least not how your are expecting to)

Submodules are a feature added to the language to address one specific question: separation of interface and implementation. The main motivation was the compile cascades generated when you needed to change just a implementation detail in a module.

But Submodules are not Modules!

A submodule is tied to a module and provides implementation to procedures declared in that module. So, a submodule have access to all declarations in it's parent module. Nonetheless, the module doesn't know anything about it's Submodules, and doesn't USE it's Submodules like they were modules. The module just expect you to add Submodules at link time, enough to cover all the missing procedure implementations.

So, if you would declare a type or anything else in a submodule, it would be local and opaque to the parent module.

If you need to access declarations of a program unity by host in another unit, a Module is what you need.

You have to design your solution wisely. Separate your modules by subject and dependency. If three types reference each other then they are very related should be in the same program unit.

Upvotes: 3

Related Questions