为具有TARGET属性的伪参数的过程提供一个没有TARGET属性的参数

时间:2015-07-10 15:44:58

标签: fortran

在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

1 个答案:

答案 0 :(得分:5)

您的代码无效是正确的。但是,由于你说的原因,它不是。

在一个过程中,即使相关的实际参数不具有目标属性,伪参数也是合法的。基本上,只要指向的生命周期不超过过程的生命周期,我们就可以在程序中指定实体。

在这个问题的情况下,即使相关的实际参数tab没有,也允许伪参数A具有目标属性。甚至程序中的指针赋值语句ptr_tab => tab也是合法的。

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

  

如果非指针伪参数具有TARGET属性且相应的实际参数不具有,则任何与伪参数关联的指针,因此与实际参数关联的指针   程序的执行,在程序执行完成时变为未定义。

也就是说,就问题而言,完成pointerize ptr_A后不再具有已定义的关联状态。

。不允许在主程序的print语句中引用此指针。

有兴趣的是,使用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)

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