Fortran 使用具有目标属性的伪参数向过程提供不具有目标属性的参数

Fortran 使用具有目标属性的伪参数向过程提供不具有目标属性的参数,fortran,Fortran,在Fortran语言中,向具有TARGET属性的伪参数的过程提供不具有TARGET属性的参数会导致代码无效。但是,当使用gfortran(5.1.0)或ifort(14.0.0)编译以下代码时,不会检测到错误,并且程序的行为与参数实际具有TARGET属性类似。当我说这是一个无效代码或者这是一个编译器缺陷时,我错了吗 program pointerization implicit none integer, dimension(3) :: A integer, dimensio

在Fortran语言中,向具有TARGET属性的伪参数的过程提供不具有TARGET属性的参数会导致代码无效。但是,当使用gfortran(5.1.0)或ifort(14.0.0)编译以下代码时,不会检测到错误,并且程序的行为与参数实际具有TARGET属性类似。当我说这是一个无效代码或者这是一个编译器缺陷时,我错了吗

program pointerization
   implicit none

   integer, dimension(3) :: A
   integer, dimension(:), pointer :: ptr_A

   A = [1, 2, 3]
   call pointerize(A, ptr_A)
   print*, "A=", ptr_A

contains
    subroutine pointerize(tab, ptr_tab)
        integer, dimension(:), intent(in), target :: tab
        integer, dimension(:), pointer :: ptr_tab

        ptr_tab => tab
    end subroutine
end program

您的代码无效,这是正确的。不过,这不是你说的原因

在过程中,伪参数具有target属性是合法的,即使关联的实际参数没有。本质上,只要指针的生命周期不超过过程的生命周期,我们就可以让指针指向过程中的实体

在这个问题中,允许伪参数
选项卡
具有target属性,即使关联的实际参数
A
没有。甚至过程中的指针赋值语句
ptr_tab=>tab
也是合法的

然而,重要的是,在过程之外,实际参数没有目标属性,我们不能通过指针影响该实体。Fortran标准确保不会以以下方式发生这种情况(Fortran 2008 C.9.4,另见12.5.2.4;Fortran 2018中也存在类似情况):

如果非指针伪参数具有TARGET属性,而对应的实际参数没有,则在 过程的执行,在过程执行完成时变为未定义

也就是说,在问题的情况下,在完成
pointerize
ptr\u时,A
不再具有定义的关联状态。不允许在主程序的打印语句中延迟此指针

出于兴趣,使用nagfor编译示例代码会导致运行时诊断

Runtime Error: aaa.f90, line 9: Reference to dangling pointer PTR_A
Target was RETURNed from procedure POINTERIZATION:POINTERIZE
Program terminated by fatal error
Abort (core dumped)

但同样,仅仅因为指针关联是未定义的,这并不意味着您无法获得预期的结果。这样的检查对于编译器来说是件好事,但并不要求它失败

作为参考,Fortran参考§C.9.6中提到了您的观点。如果您想使用程序将指针关联到变量,最好的方法是使用F08的自动定位功能。您可以将虚拟变量
tab
定义为:
整数、指针、意图(in)::tab(:)
。这样可以强制变量
A
具有target属性,从而限制未定义指针的可能性。