向具有TARGET属性的虚拟参数的过程提供不具有TARGET属性的参数

Ant*_*ine 4 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
Run Code Online (Sandbox Code Playgroud)

fra*_*lus 5

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

在过程中,即使关联的实际参数没有目标值,伪参数也具有目标属性是合法的。本质上,只要此指向的生存期不超过过程的生存期,就可以使它具有针对过程中实体的指针。

对于此问题,tab即使关联的实际参数A没有,也允许哑元参数具有target属性。甚至过程中的指针分配语句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)
Run Code Online (Sandbox Code Playgroud)

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

  • 如果要使用过程将指针与变量相关联,最好的方法是使用 F08 的自动定位功能。您可以将虚拟变量 `tab` 定义为: `integer,pointer,intent(in) :: tab(:)` 。这样你就可以强制你的变量 `A` 具有目标属性,限制了有未定义指针的可能性。 (3认同)