This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: Function pointer to internal function


Hello,

the Fortran 2008 standard allows to use an internal procedure as actual
argument to a procedure call. The C equivalent would be:

void bar (void (*fn)(void));

void test () {
  void internal () {
    printf ("Hello World\n");
  }
  bar (&internal);
}

While in Fortran it is:

subroutine test()
  external some_proc
  call some_proc (internal_proc)
contains
  subroutine internal_proc()
     write(*,*) 'Hello World'
  end subroutine internal_proc
end subroutine test

Well, if one tries the C example with GCC, the compiler just does not find
"internal" and thus it does not compile. (Fortran gives currently an error
that it is not allowed [in Fortran 2003].)

 * * *

The question is now how to implement it. As Steve Lionel points out
(cf. PR 34162), the task is not trivial. (The feature is implemented
in Intel's Fortran compiler.)
"The implementation is indeed not trivial and has to be different on
 each of the three operating systems we support, but it can be done.
 [...]
 It has to be invoked while the containing procedure is active.  You
 can't store it away somewhere and use it later. Once the containing
 procedure exits, the passed procedure 'thing' becomes undefined (as of
 course do the local variables of the containing procedure.)

 A common implementation in the past was to write onto the stack a mini-
 routine that loads a register with the context (address of a frame
 pointer, etc.) and then calls the actual procedure.  Now that
 operating systems (and processors) block execution of code from the
 stack, due to viruses taking advantage of this, other places are
 needed to store the code, but the concept is usually similar."

Thus, my question is: Does anyone see a neat way to get it working on
all targets GCC supports? If not, what is the best way to get this
working individually for all targets?

On of the crucial problems is that the contained procedure has access
to the local variables of the containing procedure - at the time it
was passed on.

Tobias

PS: The Fortran 2003 standard (which did not allow it) has the following
implementor's note:
"NOTE 12.16  This standard does not allow internal procedures to be used as
 actual arguments, in part to simplify the problem of ensuring that internal
 procedures with recursive hosts access entities from the correct instance
 (12.5.2.3) of the host. If, as an extension, a processor allows internal
 procedures to be used as actual arguments, the correct instance in this case is
 the instance in which the procedure is supplied as an actual argument, even if
 the corresponding dummy argument is eventually invoked from a different
 instance."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]