以种类参数作为子例程参数的参数化派生类型

Posted

技术标签:

【中文标题】以种类参数作为子例程参数的参数化派生类型【英文标题】:Parametrized derived types with kind parameter as subroutine argument 【发布时间】:2018-12-10 10:12:36 【问题描述】:

假设我们有以下代码:

module foo
use :: iso_fortran_env
implicit none

type :: bar (p, q)
    integer, kind :: p
    integer, len  :: q
    integer(kind = p), dimension(q) :: x
end type bar

contains

subroutine barsub (this)
    class(bar(*,*)), intent(in) :: this
    write (*,*) this%x
end subroutine barsub

end module foo

此代码不能使用 gfortran 8 或 pgfort 18.4 编译。 pgi 编译器说

非法选择器 - KIND 值必须为非负数 假定类型参数 (*) 不能与非长度类型参数一起使用 p

而 gfortran 产生

(1) 处的 KIND 参数 'p' 不能是 ASSUMED 或 DEFERRED

如果我把上面的代码改成

subroutine barsub (this)
    class(bar(INT32,*)), intent(in) :: this
    write (*,*) this%x
end subroutine barsub

两个编译器都能正常编译。

是否可以编写一个不需要明确指定种类参数的子程序?在上面的示例中,INT32INT64、... 的代码是相同的,我不想为 kind 参数的每个可以想象的值复制粘贴它。它适用于 len 参数。为什么我不能对 kind 参数做同样的事情?

【问题讨论】:

派生类型的种类参数在这方面与内在类型相同。如果您了解这些规则,则可能没有太多要添加的内容了。 可能重复? ***.com/questions/51133634/… 【参考方案1】:

是否可以编写一个不需要明确指定种类参数的子程序?

不,kind 类型参数需要由常量表达式或默认值给出,例如,参见 Fortran 2008 标准,定义 1.3.147.12.3。

为什么我不能对 kind 参数做同样的事情?

lenkind 类型参数有不同的用途和要求这一事实是拥有两种类型参数的关键,如果它们的特性相同,我们就不需要其中的两个。

请注意,过程对参数化派生类型的伪参数的kind 参数的要求与对它们内部类型的伪参数的kind 的要求相同:在编译时定义它们的值。

【讨论】:

以上是关于以种类参数作为子例程参数的参数化派生类型的主要内容,如果未能解决你的问题,请参考以下文章

使用指针来参数化函数

Perl 中带有输出参数的子例程的最佳实践命名约定

批处理脚本子例程:传递参数

Fortran字符格式字符串作为子例程参数

如何从 unix shell 调用带有参数的子例程

从 C++ 调用带有可选参数的 Fortran 子例程