定义的赋值和内部赋值(使用nagfor)之间存在冲突?

时间:2018-11-20 09:50:18

标签: fortran polymorphism gfortran intel-fortran nag-fortran

内部多态分配是某些Fortran编译器(例如ifort 18,nagfor 6.2)的最新功能,而旧版本(例如ifort 17,gfortran 6.3)不可用。适用于这些较旧版本的一种著名解决方案是使用定义的赋值,如以下示例所示(摘自Chivers and Sleightholme):

DATETIME

此示例可与ifort 15.0.3和gfortran 6.3.0一起编译并很好地工作。但是使用nagfor 6.2时,在编译过程中(对于行datetime)出现以下错误:

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file
​
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
​
​
def login_gdrive(SCOPES):
    store = file.Storage('../personal_token.json')
    creds = store.get()
    return build('drive', 'v3', http=creds.authorize(Http()))
​
def gdrive_download(file_id):
    request = drive_service.files().get(fileId=file_id)
    result = request.execute()

    #will return metadata of file but I will only get file name
    file_name = result['name']
    print(f"File name is {file_name}")

    #will get actual file
    request = drive_service.files().get_media(fileId=file_id)
    result = request.execute()
    print("Downloading " + file_name)

    #will write file using the file_name
    with open(file_name, mode="wb") as f:
        f.write(result)
    print("Finished writing " + file_name)
​
drive_service = login_gdrive(SCOPES)
​
gdrive_download('1oiD6h-ixAUTIWebEdN-jV8MO0sssoQTI')


out...  File name is sample_data_2018-10-21.csv
out...  Downloading sample_data_2018-10-21.csv
out...  Finished writing sample_data2018-10-21.csv

对于我尚不清楚,为什么这两个编译器不是要分配的多态变量,为什么要尝试在指令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 中使用定义的赋值。

当然,如果删除定义的赋值,它适用于nagfor,但不适用于其他旧编译器。您知道此错误来自何处以及如何解决吗?

1 个答案:

答案 0 :(得分:3)

我认为编译器拒绝该程序是正确的。但是,如果您与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,我们看一下给定的点:

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

我们满足了作为已定义分配的所有要求:没有要求指出已定义分配要求所选子例程是可调用的!

总结:

  

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

因为使用定义的分配与左手边和右手边是多态的还是可分配的无关。

最后,我认为无论我的推理是正确还是不正确,编译器的诊断消息都可以得到改善。