定义赋值和内在赋值(使用nagfor)之间存在冲突? [英] Conflict between defined assignment and intrinsic assignment (with nagfor)?

查看:0
本文介绍了定义赋值和内在赋值(使用nagfor)之间存在冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

本征多态赋值是某些Fortran编译器(例如ifort 18、nagfor 6.2)的最新功能,在旧版本(例如ifort 17、gfortran 6.3)中不提供。适用于这些旧版本的一个众所周知的解决方案是使用以下示例中定义的赋值(取自《齐弗斯与史莱特姆》一书并改编自该书):

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很好地配合使用。但是对于nagfor6.2,我在编译过程中得到以下错误(对于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_assignLIKE

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,我们查看给定点:

  1. generic_shape_assign是具有两个伪参数的子例程(此处为lhsrhs);
  2. 接口块提供generic_shape_assign通用规范assignment(=)
  3. lhs(类型shape_t)与mycirc2(动态类型circle_t)类型兼容;rhs相似;
  4. 没有用于伪参数或实参的类型参数;
  5. 伪参数和实际参数的等级(标量)匹配。

我们满足作为已定义赋值的所有要求:没有要求已定义赋值要求所选子例程是可调用的!

小结:

我不清楚为什么此编译器尝试使用指令mycirc2 = mycirc1中定义的赋值,而这两个变量不是可分配的多态变量。

因为是否使用定义的赋值与左侧和右侧是多态的还是可分配的无关。

最后,我认为无论我的推理正确与否,来自编译器的诊断消息都可以得到改进。

这篇关于定义赋值和内在赋值(使用nagfor)之间存在冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆