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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…