[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