Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

fortran

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
like image 262
Antoine Lemoine Avatar asked Jul 10 '15 15:07

Antoine Lemoine


1 Answers

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.

like image 167
francescalus Avatar answered Oct 18 '22 21:10

francescalus