Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29253 ディスカッション

PROCEDURE declaration in v11

ender01
新規コントリビューター I
857件の閲覧回数

Hello all,

I'm trying to figure out the PROCEDURE declaration and I can't get it to work. For example, with the module and main:

module proc_component_example
type t
real :: a
procedure(print_me), pointer, nopass :: proc

end_type t
contains
subroutine print_me (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a
end subroutine print_me
subroutine print_my_square (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a**2
end subroutine print_my_square
end module proc_component_example


program main
use proc_component_example
use iso_fortran_env, only :: output_unit
type(t) :: x
x%a = 2.71828
x%proc => print_me
call x%proc(x, output_unit)
x%proc => print_my_square
call x%proc(x, output_unit)
end program main

I get a compilation error #8169: The specified interface is not declared. [PRINT_ME]. If I add an interface, a la

interface print_me
module procedure print_me
end interface

I get another compilation error #8182: The name is neither an abstract interface nor a procedure with an explicit interface. [PRINT_ME].

If I add an abstract interface I get yet another error #6457: This derived type name has not been declared.

What am I missing?

Thanks

0 件の賞賛
1 解決策
Steven_L_Intel1
従業員
857件の閲覧回数

Offhand, I think your example should work. I recall that I submitted a bug report about similar behavior recently, the bug is not yet fixed. However, the following works. Note the required IMPORT to make T visible in the interface. Also, the ordering of the declarations seems to matter (though I don't think it should.)

[cpp]module proc_component_example
type t
real :: a
procedure(print_int), pointer, nopass :: proc
end type t

abstract interface
subroutine print_int (arg, lun)
import
type(t), intent(in) :: arg
integer, intent(in) :: lun
end subroutine print_int
end interface

contains
subroutine print_me (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a
end subroutine print_me
subroutine print_my_square (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a**2
end subroutine print_my_square
end module proc_component_example


program main
use proc_component_example
use iso_fortran_env, only : output_unit
type(t) :: x
x%a = 2.71828
x%proc => print_me
call x%proc(x, output_unit)
x%proc => print_my_square
call x%proc(x, output_unit)
end program main[/cpp]

元の投稿で解決策を見る

4 返答(返信)
Steven_L_Intel1
従業員
858件の閲覧回数

Offhand, I think your example should work. I recall that I submitted a bug report about similar behavior recently, the bug is not yet fixed. However, the following works. Note the required IMPORT to make T visible in the interface. Also, the ordering of the declarations seems to matter (though I don't think it should.)

[cpp]module proc_component_example
type t
real :: a
procedure(print_int), pointer, nopass :: proc
end type t

abstract interface
subroutine print_int (arg, lun)
import
type(t), intent(in) :: arg
integer, intent(in) :: lun
end subroutine print_int
end interface

contains
subroutine print_me (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a
end subroutine print_me
subroutine print_my_square (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a**2
end subroutine print_my_square
end module proc_component_example


program main
use proc_component_example
use iso_fortran_env, only : output_unit
type(t) :: x
x%a = 2.71828
x%proc => print_me
call x%proc(x, output_unit)
x%proc => print_my_square
call x%proc(x, output_unit)
end program main[/cpp]

ender01
新規コントリビューター I
857件の閲覧回数

Offhand, I think your example should work. I recall that I submitted a bug report about similar behavior recently, the bug is not yet fixed. However, the following works. Note the required IMPORT to make T visible in the interface. Also, the ordering of the declarations seems to matter (though I don't think it should.)

[cpp]module proc_component_example
type t
real :: a
procedure(print_int), pointer, nopass :: proc
end type t

abstract interface
subroutine print_int (arg, lun)
import
type(t), intent(in) :: arg
integer, intent(in) :: lun
end subroutine print_int
end interface

contains
subroutine print_me (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a
end subroutine print_me
subroutine print_my_square (arg, lun)
type(t), intent(in) :: arg
integer, intent(in) :: lun
write (lun,*) arg%a**2
end subroutine print_my_square
end module proc_component_example


program main
use proc_component_example
use iso_fortran_env, only : output_unit
type(t) :: x
x%a = 2.71828
x%proc => print_me
call x%proc(x, output_unit)
x%proc => print_my_square
call x%proc(x, output_unit)
end program main[/cpp]

Thanks Steve,

I'd missed the import, I didn't think I needed it as t wasn't private. Also, what do you mean that the declaration order is important? My understanding is that the import will only make objects available that have been declared prior to the interface body. Is that what you mean?

Thanks again!

Rich

Steven_L_Intel1
従業員
857件の閲覧回数

My comment wasn't in regard to IMPORT, but rather there seems to be a required order for the interface and its use in PROCEDURE. I don't think there should be an order - if an explicit interface is visible, then it should be usable. I think this is a compiler bug and will bring it to the attention of the developers.

The IMPORT is required in an interface block if you want any of the host symbols to be visible. See my blog post on IMPORT for more details.

Steven_L_Intel1
従業員
857件の閲覧回数
The bug, our issue DPD200051171, is that an ABSTRACT INTERFACE cannot be host-associated. It can be use-associated, however. This is fixed for a release later this year.
返信