【问题标题】:Optional arguments in type bound subroutines in Fortran 2008Fortran 2008 中类型绑定子例程中的可选参数
【发布时间】:2015-08-22 00:37:29
【问题描述】:

调用类型绑定子例程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

除了stackoverflow“可能已经有你答案的问题”之外,我们还阅读了http://comments.gmane.org/gmane.comp.gcc.fortran/33604https://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

【问题讨论】:

  • 第一个警告只是一个警告。如果是假的,请忽略它!我使用-Wno-unused-dummy-argument 自动忽略它们,它们只是一个麻烦。
  • 编译器警告指出了@casey 能够解决的我理解的空白。

标签: class types fortran polymorphic-associations gfortran


【解决方案1】:

在我看来,调用此函数有两种选择——使用或传递对象的虚拟参数。

在你拥有的版本中,

... 
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 供进一步阅读。

【讨论】:

  • 解释很有帮助。谢谢。
猜你喜欢
  • 2021-06-15
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
相关资源
最近更新 更多