This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFC: Function pointer to internal function
- From: Tobias Burnus <tobias dot burnus at physik dot fu-berlin dot de>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Fri, 3 Sep 2010 10:38:43 +0200
- Subject: 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."