Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
579 views
in Technique[技术] by (71.8m points)

fortran - Providing an argument that has not the TARGET attribute to a procedure with a dummy argument that has the TARGET attribute

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.

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):

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.

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...