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

ifort fails silently with nested TBP call

Ramanathan_V_
Beginner
353 Views

Hello,

I'm using:

$ ifort --version
ifort (IFORT) 15.0.0 20140723
Copyright (C) 1985-2014 Intel Corporation.  All rights reserved.

The following Fortran code:

module B_mod

  type :: t_B
   contains
     procedure, pass :: foo_B
     procedure, pass :: bar_B
  end type t_B

  interface
     subroutine foo_B(this)
       import :: t_B
       class(t_B) :: this
     end subroutine foo_B
  end interface

  interface
     subroutine bar_B(this)
       import :: t_B
       class(t_B) :: this
     end subroutine bar_B
  end interface

end module B_mod

module A_mod

  use B_mod, only : t_B

  type :: t_A
     type(t_B) :: b
   contains
     procedure, pass :: foo_A
  end type t_A

  interface
     subroutine foo_A(this)
       import :: t_A
       class(t_A) :: this
     end subroutine foo_A
  end interface

end module A_mod

program main
  use A_mod, only : t_A
  integer :: ierror
  type(t_A) :: a
  call a%foo_A()
end program main

subroutine foo_A(this)
  use A_mod, only : t_A
  class(t_A) :: this
  call this%b%foo_B()
end subroutine foo_A

subroutine foo_B(this)
  use B_mod, only : t_B
  class(t_B) :: this
  print *, "this is printed ..."
  call this%bar_B()
end subroutine foo_B

subroutine bar_B(this)
  use B_mod, only : t_B
  class(t_B) :: this
  print *, "... but this is not"
end subroutine bar_B

produces the output:

 this is printed ...

whereas the expected output is

 this is printed ...
 ... but this is not

I'm declaring an explicit interface in the modules where my derived types are declared, and choosing to define the subroutines outside the module. This is closer to the C++ way of separating definition/declaration. If I remove the interface declarations and define the subroutines within the module, as in:

module B_mod

  type :: t_B
   contains
     procedure, pass :: foo_B
     procedure, pass :: bar_B
  end type t_B

contains

  subroutine foo_B(this)
    class(t_B) :: this
    print *, "this is printed ..."
    call this%bar_B()
  end subroutine foo_B

  subroutine bar_B(this)
    class(t_B) :: this
    print *, "... but this is not"
  end subroutine bar_B

end module B_mod

module A_mod

  use B_mod, only : t_B

  type :: t_A
     type(t_B) :: b
   contains
     procedure, pass :: foo_A
  end type t_A

contains

  subroutine foo_A(this)
    class(t_A) :: this
    call this%b%foo_B()
  end subroutine foo_A
  
end module A_mod

program main
  use A_mod, only : t_A
  integer :: ierror
  type(t_A) :: a
  call a%foo_A()
end program main

then, the expected output is produced. Does this mean I can't separate the defintion of type-bound procedures from their declaration? As a side note, does ifort support submodules, which seem to be a way of doing this more elegantly?

0 Kudos
2 Replies
FortranFan
Honored Contributor III
353 Views

So is it simply a separation of definition and declaration you're after?  Then do look into submodules in 16.0 beta - see this link.  Or is it procedure pointers you're after, as illustrated here?

0 Kudos
Ramanathan_V_
Beginner
353 Views

FortranFan wrote:

So is it simply a separation of definition and declaration you're after?  Then do look into submodules in 16.0 beta - see this link.  Or is it procedure pointers you're after, as illustrated here?

I'm just interested in separating definition and declaration with this approach. It's nice that support for submodules is coming with 16.0 beta, but I mainly use ifort on supercomputers which have slightly outdated versions. To maintain portability, I need to be able to write code that compiles with older ifort versions. Most of the clusters I'm running on have ifort 14 and 15.

0 Kudos
Reply