Interface Fortran中显式接口的正确实现
我正在努力使用Fortran中的显式接口 在一个实例中,当我试图使用假定的形状数组作为函数或子例程(即过程)的伪参数时,编译器要求我编写一个显式接口:Interface Fortran中显式接口的正确实现,interface,fortran,Interface,Fortran,我正在努力使用Fortran中的显式接口 在一个实例中,当我试图使用假定的形状数组作为函数或子例程(即过程)的伪参数时,编译器要求我编写一个显式接口:explicit interface required for。。。假定形状参数。例如,这将在子例程中显示为REAL,INTENT(IN-OUT)::dummy_数组(:)。数组声明中的(:)表示编译器负责将有关数组形状的信息传递给子例程。这很方便,但也意味着编译器在编译对过程的调用或引用时必须知道这样做。仅从调用(或引用)就看不出这一点,因此编译
explicit interface required for。。。假定形状参数
。例如,这将在子例程中显示为REAL,INTENT(IN-OUT)::dummy_数组(:)
。数组声明中的(:)
表示编译器负责将有关数组形状的信息传递给子例程。这很方便,但也意味着编译器在编译对过程的调用或引用时必须知道这样做。仅从调用
(或引用)就看不出这一点,因此编译器必须具有有关过程伪参数的信息,因此需要显式接口
据我所知,在Fortran中实现显式接口有三种方法:
模块。这往往是推荐的方法
END
语句之前放置一个CONTAINS
语句。然后,我的整个过程代码将放在这两个语句之间接口
。我想大多数人都默认这一点,但这往往是最不推荐的方法,因为它可能有点费劲MODULE My_Module
CONTAINS
SUBROUTINE Clean(my_array_sizes, my_arrays, my_arrays_clean)
USE Shared, ONLY : dp
IMPLICIT NONE
...
REAL(dp), INTENT(OUT), ALLOCATABLE, ASYNCHRONOUS :: my_arrays_clean(:)
...
ALLOCATE(my_arrays_clean(non_zero)) !new array of correct size
my_arrays_clean = temp(1:non_zero) !transfer values
END SUBROUTINE Clean
END MODULE My_Module
问题似乎在于虚拟数组my\u arrays\u clean
。这是电话:
CALL Clean(my_array_size, probability, probability_clean) !remove empty values from array
概率清洁的声明:
REAL(dp), DIMENSION(:), ALLOCATABLE, ASYNCHRONOUS :: probability, probability_clean !store Photon(E_i, depth) values
在我尝试使用
gfortran-g-std=f2008-Wall-Wextra-O2-fall intrinsics-fopenmp编译之前,一切似乎都很好:对“clean”的未定义引用。我不知道怎么了。当然,我可以解决这个问题来完成我所需要的,但我真的很想了解正确的方法。当我们讨论显式(或隐式)接口时,我们并不是在讨论过程本身的属性。一个过程有一个接口,但这不是完全相同的概念。取下面的模块和子程序
module mod
contains
subroutine sub
end subroutine
end module
子例程sub
有一个接口,包括这样的信息:它是一个名为sub
的子例程,没有伪参数。问题中感兴趣的子例程有自己相应的接口
相反,“显式接口”是关于在引用该过程的点上,该过程接口的已知信息。看
call sub
end
并将其与
use mod, only : sub
call sub
end
在第一种情况下,如果不使用模块mod
,编译器甚至不能将sub
视为模块内的子例程sub
这里是一个带有隐式接口的外部过程(而不是模块中的过程)。在第二种情况下,sub
是使用关联的;编译器现在不仅可以看到模块子例程,还可以看到接口(现在是显式的)
同样,内部过程(第2项。使用包含语句)在其宿主中始终具有显式接口:
第三,使用接口块:
subroutine sub
end subroutine
interface
subroutine sub
end subroutine
end interface
call sub
end program
总之:可访问的模块过程总是有一个明确的可用接口,但必须首先通过use
语句使其可访问。内部过程始终可以在主机中访问,并且始终具有显式接口。接口块提供了一个显式接口,但接口块本身必须位于过程引用的位置。当我们讨论显式(或隐式)接口时,我们并不是在讨论过程本身的属性。一个过程有一个接口,但这不是完全相同的概念。取下面的模块和子程序
module mod
contains
subroutine sub
end subroutine
end module
子例程sub
有一个接口,包括这样的信息:它是一个名为sub
的子例程,没有伪参数。问题中感兴趣的子例程有自己相应的接口
相反,“显式接口”是关于在引用该过程的点上,该过程接口的已知信息。看
call sub
end
并将其与
use mod, only : sub
call sub
end
在第一种情况下,如果不使用模块mod
,编译器甚至不能将sub
视为模块内的子例程sub
这里是一个带有隐式接口的外部过程(而不是模块中的过程)。在第二种情况下,sub
是使用关联的;编译器现在不仅可以看到模块子例程,还可以看到接口(现在是显式的)
同样,内部过程(第2项。使用包含语句)在其宿主中始终具有显式接口:
第三,使用接口块:
subroutine sub
end subroutine
interface
subroutine sub
end subroutine
end interface
call sub
end program
总之:可访问的模块过程总是有一个明确的可用接口,但必须首先通过use
语句使其可访问。内部过程始终可以在主机中访问,并且始终具有显式接口。接口块提供了一个明确的接口,但接口块本身也必须在进行过程引用的位置附近。看起来您缺少了一个使用my_module
,其中有调用clean(…)
。请给出一个完整的例子以获得更多帮助。我同意这里的@francescalus。gfortran将模块过程的名称更改为类似“MOD\u my\u module\u clean”的名称。带有clean的错误消息_