fortran - 定义的赋值和内在赋值之间的冲突(使用 nagfor)?
问题描述
内在多态赋值是一些 Fortran 编译器(例如 ifort 18、nagfor 6.2)的最新功能,在旧版本(例如 ifort 17、gfortran 6.3)中不可用。与这些旧版本一起使用的众所周知的解决方案是使用如下示例中定义的分配(取自 Chivers 和 Sleightholme 的书并改编自):
module deftypes
type, abstract :: shape_t
integer :: x = 0, y = 0
end type shape_t
type, extends(shape_t) :: circle_t
integer :: radius = 0
end type circle_t
interface assignment(=)
module procedure generic_shape_assign
end interface
contains
subroutine generic_shape_assign ( lhs, rhs )
class(shape_t), intent(in ) :: rhs
class(shape_t), allocatable, intent(out) :: lhs
print*,' --> in generic_shape_assign'
allocate(lhs, source = rhs)
end subroutine generic_shape_assign
end module deftypes
program check_assign
use deftypes
implicit none
class(shape_t), allocatable :: myshape
type (circle_t) :: mycirc1, mycirc2
mycirc1 = circle_t ( 1, 2, 3 )
print*,'A polymorphic assignment: myshape = mycirc1'
myshape = mycirc1
print*,'An intrinsic assignment: mycirc2 = mycirc1'
mycirc2 = mycirc1
end program check_assign
此示例可与 ifort 15.0.3 和 gfortran 6.3.0 一起编译并运行良好。但是对于 nagfor 6.2,我在编译期间收到以下错误(对于 line mycirc2=mycirc1
):
Error: check_assign.f90, line 41: Incorrect data type CIRCLE_T (expected SHAPE_T) for argument LHS (no. 1) of GENERIC_SHAPE_ASSIGN
我不清楚为什么这个编译器试图在指令中使用定义的赋值,mycirc2 = mycirc1
而这两个变量不是可分配的多态变量。
当然,如果我删除定义的赋值,它适用于 nagfor 但不适用于其他旧编译器。知道这个错误来自哪里以及如何解决它吗?
解决方案
我相信编译器拒绝这个程序是正确的。但是,如果您与 NAG 签订了支持合同,我强烈建议您让他们不要将我的意见视为确定性意见。
我会展示我的推理。
很明显,对具体程序的引用generic_shape_assign
就像
type(circle_t) mycirc1, mycirc2
call generic_shape_assign(mycirc2, mycirc1)
无效。它失败是因为实际参数mycirc2
,对应于可分配的多态虚拟参数lhs
:
- 不可分配;
- 与相应的虚拟参数的声明类型不同;
- 不是多态的。
您引用的错误消息涵盖了因违反这一秒而被拒绝的程序。
那么,这意味着这generic_shape_assign
不是具有通用规范的有效特定程序(供本参考)assignment(=)
,对吧?因此没有选择定义的赋值,编译器应该退回到内在赋值?
这就是事情变得模糊的地方(至少对我而言)。
我认为为定义的分配选择了特定的子例程generic_shape_assign
,因此编译器拒绝您的程序是正确的,因为您没有正确调用这个特定的子例程。
让我们进一步看一下,使用 Fortran 2008 7.2.1.4,其中定义了赋值语句何时是已定义的赋值语句。
要确定子例程是否generic_shape_assign
定义了定义的赋值语句mycirc2=mycirc1
,我们查看给定点:
generic_shape_assign
是一个带有两个虚拟参数的子程序(这里是lhs
和rhs
);- 接口块给出
generic_shape_assign
了通用规范assignment(=)
; lhs
(类型shape_t
)与mycirc2
(动态类型circle_t
)兼容;rhs
相似地;- 虚拟或实际参数没有类型参数;
- 虚拟参数和实际参数的等级(标量)匹配。
我们满足了定义赋值的所有要求:没有要求声明定义的赋值要求所选子例程是可调用的!
总之:
我不清楚为什么这个编译器试图在指令中使用定义的赋值,
mycirc2 = mycirc1
而这两个变量不是可分配的多态变量。
因为是否使用定义的赋值与左侧和右侧是多态还是可分配无关。
最后,我认为无论我的推理是正确还是不正确,编译器的诊断信息都可以改进。
推荐阅读
- node.js - 将监听端口 localhost:8080 的当前 nodejs api 链接到 localhost:4200 的角度
- matlab - 我的 ubuntu 18.0.4 不会从安装中创建“matlab”文件
- scala - 如何使用类型成员约束与类型类一起使用?
- php - PHP地理插件不起作用
- excel - Excel vba宏在满足条件时将列的一部分向下移动一行
- python - 查找与先前元素的元素的平均值并将其求和并平均
- delphi - 如何在我的 Delphi 控制台应用程序中运行控制台应用程序?
- python - 通过 OCG(按层)从 PDF 中提取几何元素
- .htaccess - Symfony htaccess 到子文件夹
- javascript - HTML