在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)
您是正确的,您有无效的代码。不过,这并不是您说的原因。
在过程中,即使关联的实际参数没有目标值,伪参数也具有目标属性是合法的。本质上,只要此指向的生存期不超过过程的生存期,就可以使它具有针对过程中实体的指针。
对于此问题,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)
但是同样地,仅由于未定义指针关联,并不意味着您无法获得期望的结果。对于编译器来说,这样的检查是一件好事,但是并不需要它失败。
| 归档时间: |
|
| 查看次数: |
335 次 |
| 最近记录: |