Fortran 2008 中类型绑定子例程中的可选参数
Optional arguments in type bound subroutines in Fortran 2008
调用类型绑定子例程的最佳方法是什么 seed_rng
?
以下代码的编译命令gfortran -Wall mwe.f90
产生警告
subroutine seed_rng_sub ( self, checkOS, mySeed )
1
Warning: Unused dummy argument ‘self’ at (1) [-Wunused-dummy-argument]
对于初学者来说,这建议删除子例程定义中的 self
参数(即使用 subroutine seed_rng_sub ( checkOS, mySeed )
)。然而,这会产生错误
procedure, public :: seed_rng => seed_rng_sub
1
Error: Non-polymorphic passed-object dummy argument of ‘seed_rng_sub’ at (1)
和
class ( randomNumber ), target :: self
1
Error: CLASS variable ‘self’ at (1) must be dummy, allocatable or pointer
除了 Whosebug "Questions that may already have your answer",我们还阅读了 http://comments.gmane.org/gmane.comp.gcc.fortran/33604 and https://gcc.gnu.org/ml/fortran/2010-09/msg00221.html 上的讨论,但没有成功。
主程序:
include 'mod test.f90'
program mwe
use mTest
implicit none
type ( randomNumber ) :: rnumber
call rnumber % seed_rng ( .true. )
end program mew
模块:
module mTest
use iso_fortran_env, only: int64, real64
implicit none
type, public :: randomNumber
real ( kind ( real64 ) ) :: x
contains
private
! subroutines
procedure, public :: seed_rng => seed_rng_sub
end type randomNumber
private :: seed_rng_sub
contains
subroutine seed_rng_sub ( self, checkOS, mySeed )
use iso_fortran_env, only: int64
class ( randomNumber ), target :: self
integer, intent ( IN ), optional :: mySeed ( 1 : 12 )
logical, intent ( IN ), optional :: checkOS
integer :: n = 0
integer, allocatable :: seed ( : )
integer, parameter :: s0 ( 1 : 12 ) = [ 155719726, 156199294, 156319186, 156439078, 156678862, 156918646, &
157198394, 157318286, 157398214, 157438178, 157518106, 157877782 ]
call random_seed ( size = n )
allocate ( seed ( n ) )
if ( present ( mySeed ) ) then
call random_seed ( put = mySeed )
return
end if
present_checkOS: if ( present ( checkOS ) ) then
if ( checkOS ) then
call random_seed ( put = s0 )
return
else
exit present_checkOS
end if
end if present_checkOS
call random_seed ( put = s0 )
end subroutine seed_rng_sub
end module mTest
据我所知,调用此函数有两种选择——使用或传递对象虚拟参数。
在您的版本中,
...
procedure, public :: seed_rng => seed_rng_sub
...
subroutine seed_rng_sub ( self, checkOS, mySeed )
...
class ( randomNumber ), target :: self
...
您将收到未使用 self
时看到的警告。如果你想避免警告,你可以不传递传递的对象,更改上面的前两行并删除第三行:
...
procedure, nopass, public :: seed_rng => seed_rng_sub
...
subroutine seed_rng_sub (checkOS, mySeed )
...
过程的 nopass
属性告诉 Fortran 不要传递传递对象伪参数,因此您可以从子例程声明中删除它并从该子例程中删除变量。当您尝试更改子例程时出现错误的原因是没有 nopass
属性,您仍在指定过程第一个参数是传递的对象伪参数并且您的过程不匹配。见分类。 4.5.4.5 Fortran 2008 进一步阅读。
调用类型绑定子例程的最佳方法是什么 seed_rng
?
以下代码的编译命令gfortran -Wall mwe.f90
产生警告
subroutine seed_rng_sub ( self, checkOS, mySeed )
1
Warning: Unused dummy argument ‘self’ at (1) [-Wunused-dummy-argument]
对于初学者来说,这建议删除子例程定义中的 self
参数(即使用 subroutine seed_rng_sub ( checkOS, mySeed )
)。然而,这会产生错误
procedure, public :: seed_rng => seed_rng_sub
1
Error: Non-polymorphic passed-object dummy argument of ‘seed_rng_sub’ at (1)
和
class ( randomNumber ), target :: self
1
Error: CLASS variable ‘self’ at (1) must be dummy, allocatable or pointer
除了 Whosebug "Questions that may already have your answer",我们还阅读了 http://comments.gmane.org/gmane.comp.gcc.fortran/33604 and https://gcc.gnu.org/ml/fortran/2010-09/msg00221.html 上的讨论,但没有成功。
主程序:
include 'mod test.f90'
program mwe
use mTest
implicit none
type ( randomNumber ) :: rnumber
call rnumber % seed_rng ( .true. )
end program mew
模块:
module mTest
use iso_fortran_env, only: int64, real64
implicit none
type, public :: randomNumber
real ( kind ( real64 ) ) :: x
contains
private
! subroutines
procedure, public :: seed_rng => seed_rng_sub
end type randomNumber
private :: seed_rng_sub
contains
subroutine seed_rng_sub ( self, checkOS, mySeed )
use iso_fortran_env, only: int64
class ( randomNumber ), target :: self
integer, intent ( IN ), optional :: mySeed ( 1 : 12 )
logical, intent ( IN ), optional :: checkOS
integer :: n = 0
integer, allocatable :: seed ( : )
integer, parameter :: s0 ( 1 : 12 ) = [ 155719726, 156199294, 156319186, 156439078, 156678862, 156918646, &
157198394, 157318286, 157398214, 157438178, 157518106, 157877782 ]
call random_seed ( size = n )
allocate ( seed ( n ) )
if ( present ( mySeed ) ) then
call random_seed ( put = mySeed )
return
end if
present_checkOS: if ( present ( checkOS ) ) then
if ( checkOS ) then
call random_seed ( put = s0 )
return
else
exit present_checkOS
end if
end if present_checkOS
call random_seed ( put = s0 )
end subroutine seed_rng_sub
end module mTest
据我所知,调用此函数有两种选择——使用或传递对象虚拟参数。
在您的版本中,
...
procedure, public :: seed_rng => seed_rng_sub
...
subroutine seed_rng_sub ( self, checkOS, mySeed )
...
class ( randomNumber ), target :: self
...
您将收到未使用 self
时看到的警告。如果你想避免警告,你可以不传递传递的对象,更改上面的前两行并删除第三行:
...
procedure, nopass, public :: seed_rng => seed_rng_sub
...
subroutine seed_rng_sub (checkOS, mySeed )
...
过程的 nopass
属性告诉 Fortran 不要传递传递对象伪参数,因此您可以从子例程声明中删除它并从该子例程中删除变量。当您尝试更改子例程时出现错误的原因是没有 nopass
属性,您仍在指定过程第一个参数是传递的对象伪参数并且您的过程不匹配。见分类。 4.5.4.5 Fortran 2008 进一步阅读。