[J3] [EXTERNAL] [BULK] Procedure pointers to internal procedures contained in subprogram
Clune, Thomas L. (GSFC-6101)
thomas.l.clune at nasa.gov
Thu Sep 26 19:46:33 UTC 2024
Looks ok to me. I’ll add that NAG accepts the code and produces:
11
21
31
41
51
The intent is to allow access to such local variables, but I find it is usually cleaner to bundle the procedure point with the data item. Provides more explicit control of what is going on. Of course sometimes you really do want access to that local variable remotely. Just rare in my experience.
* Tom
From: J3 <j3-bounces at mailman.j3-fortran.org> on behalf of Thomas König via J3 <j3 at mailman.j3-fortran.org>
Date: Thursday, September 26, 2024 at 3:36 PM
To: General J3 interest list <j3 at mailman.j3-fortran.org>
Cc: Thomas König <tk at tkoenig.net>
Subject: [EXTERNAL] [BULK] [J3] Procedure pointers to internal procedures contained in subprogram
CAUTION: This email originated from outside of NASA. Please take care when clicking links or opening attachments. Use the "Report Message" button to report suspicious messages to the NASA SOC.
Hello,
I have a question regarding procedure pointers.
In the following little program, the subroutine extsub saves
procedure pointers to the internal subroutine intsub from
different instances of callit. That saves them into the
array cache, and later calls them from yet another instance,
in reverse order, via calling do_things.
This appears to work with gfortran, but I can easily see case where
this could be problematic. Assume the invocation is far away from
the point where the pointer is saved; the memory location containing
local_var could long since have been overwritten with something else
by an optimizing compiler.
Is this allowed by the standard? I didn't find anything that said it's
not, but I may have overlooked something.
If it is actually allowed by the standard, is this an intentional
feature?
Best regards
Thomas König
module stash_things
implicit none
abstract interface
subroutine sub()
end subroutine sub
end interface
type cache_proc_pointer
procedure(sub), pointer, nopass :: p
integer :: n
end type cache_proc_pointer
type (cache_proc_pointer), dimension(100) :: cache
integer :: n_sub = 0
contains
recursive subroutine extsub (subname, n)
procedure(sub), pointer :: subname
integer, intent(in) :: n
n_sub = n_sub + 1
cache(n_sub)%p => subname
cache(n_sub)%n = n
end subroutine extsub
subroutine do_things()
integer :: i
do i=n_sub,1,-1
call cache(i)%p()
end do
end subroutine do_things
end module stash_things
recursive subroutine callit(n)
use stash_things
integer, intent(in) :: n
integer :: localvar
procedure(sub), pointer :: p
if (n <= 0) then
call do_things
return
end if
localvar = 1+10*n
p => intsub
call extsub(p,n)
call callit(n-1)
contains
recursive subroutine intsub
print *, localvar
end subroutine intsub
end subroutine callit
program thunk
use stash_things
implicit none
call callit(5)
end program thunk
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20240926/03ed8759/attachment-0001.htm>
More information about the J3
mailing list