将不具有 TARGET 属性的参数提供给具有 TARGET 属性的虚拟参数的过程 [英] Providing an argument that has not the TARGET attribute to a procedure with a dummy argument that has the TARGET attribute

查看:25
本文介绍了将不具有 TARGET 属性的参数提供给具有 TARGET 属性的虚拟参数的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Fortran 语言中,将不具有 TARGET 属性的参数提供给具有 TARGET 属性的虚拟参数的过程会导致无效代码.但是,当使用 gfortran (5.1.0) 或 ifort (14.0.0) 编译以下代码时,不会检测到错误并且程序的行为就像参数实际上具有 TARGET 属性一样.当我说这是无效代码还是编译器缺陷时,我错了吗?

In Fortran language, providing an argument that has not the TARGET attribute to a procedure with a dummy argument that has the TARGET attribute should lead to an invalid code. However, when the following code is compiled with gfortran (5.1.0) or ifort (14.0.0), no error is detected and the program behaves like the argument actually has the TARGET attribute. Am I wrong when I say it is an invalid code or is this a compiler defect?

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

推荐答案

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

You are correct that you have invalid code. It isn't, though, for the reason you say.

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

Within a procedure, it is legal for a dummy argument to have the target attribute even though the associated actual argument hasn't. Essentially, we are allowed to have pointers targeting the entity within the procedure as long as the lifetime of this pointing doesn't exceed the lifetime of the procedure.

在这个问题的情况下,允许虚拟参数 tab 具有目标属性,即使关联的实际参数 A 没有.连指针赋值语句ptr_tab =>;程序内的tab是合法的.

In the case of this question, the dummy argument tab is allowed to have the target attribute even though the associated actual argument A hasn't. Even the pointer assignment statement ptr_tab => tab within the procedure is legal.

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

What is important, however, is that outside the procedure, where the actual argument hasn't the target attribute, we can't affect that entity through a pointer. The Fortran standard ensures this doesn't happen in the following way (Fortran 2008 C.9.4, see also 12.5.2.4; similar exists in Fortran 2018):

如果非指针伪参数具有 TARGET 属性而相应的实际参数没有,则任何与伪参数相关联的指针,因此与实际参数相关联,在过程的执行,当过程的执行完成时变得未定义.

If a nonpointer dummy argument has the TARGET attribute and the corresponding actual argument does not, any pointers that become associated with the dummy argument, and therefore with the actual argument, during execution of the procedure, become undefined when execution of the procedure completes.

也就是说,在问题的情况下,完成 pointerize ptr_A 不再具有已定义的关联状态.不允许在主程序的 print 语句中引用此指针.

That is, in the case of the question, on completion of pointerize ptr_A is no longer of defined association status. Deferencing this pointer in the main program's print statement is not allowed.

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

For interest, compiling the example code with nagfor results in the run-time diagnostic

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)

但同样,仅仅因为指针关联是未定义的,这并不意味着你不能得到你期望的结果.这种检查对编译器来说是一件好事,但它并不一定会失败.

But equally, just because the pointer association is undefined, this doesn't mean that you can't get the results you expect. Such checking is a nice thing from a compiler but it isn't required that it should fail.

这篇关于将不具有 TARGET 属性的参数提供给具有 TARGET 属性的虚拟参数的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆