From: burley@apple-gunkies.gnu.ai.mit.edu (Craig Burley)
Newsgroups: comp.lang.fortran
Subject: ENTRY (was Re: Jumping from nested subroutine to main directly?)
Date: 23 Nov 92 10:51:06
Organization: Free Software Foundation 545 Tech Square Cambridge, MA 02139
	<DODD.92Nov21071326@mycenae.cchem.berkeley.edu>
	<By2xxC.JAB@mentor.cc.purdue.edu>
	<1992Nov21.222705.20726@monu6.cc.monash.edu.au>
NNTP-Posting-Host: apple-gunkies.gnu.ai.mit.edu
In-reply-to: map@hal.maths.monash.edu.au's message of Sat, 21 Nov 1992 22:27:05 GMT

In article <1992Nov21.222705.20726@monu6.cc.monash.edu.au> map@hal.maths.monash.edu.au (Michael Page) writes:

   One way to almost do what he wants is to use an ENTRY statement at the 
   point he wants to return to in the main program.  However, I suspect he 
   wants something a bit more `automatic' than that, but I don't think it 
   exists in FORTRAN.  Does it exist in C, Pascal, ..?

No, ENTRY is not the solution, because a) it is not allowed in a main
program unit (or BLOCK DATA, for that matter); b) even if it was, you'd
just be activating a new procedure corresponding to the main program
unit at a different starting point, not getting back to the old one; and
c) even if that worked, it essentially would amount to an attempt at
recursion, though you probably don't _want_ recursion in terms of activiting
a new set of local variables.  (I.e. why do you want to go back to MAIN?
To share code between the normal return path and the special path?  To
share variables you don't want to put in COMMON?  Because your system
somehow requires a special action from MAIN's stack frame?)

To solve the problem at hand, either use a nonportable construct like a
non-local GOTO (for example, perhaps there's a facility on your system for
accessing, say, C's setjmp/longjmp or PL/1's signalling mechanism from
Fortran), or for portability on any ANSI FORTRAN 77 system, use alternate
returns.  The latter requires that all possible intervening procedures be
subroutines and have at least one alternate-return argument that, when
selected, just causes its caller's alternate-return argument to be selected,
as in the following:

	PROGRAM FOO
	...
	CALL SUBR1(...,*999)
	...
999	(cleanup code)
	END

	SUBROUTINE SUBR1(...,*)
	...
	CALL SUBR2(...,*999)
	...
999	RETURN 1	(assumes the * is the first such in the dummy arglist)
	END

	SUBROUTINE SUBR2(...,*)
	...
	CALL SUBR3(...,*999)	(SUBR3 omitted for brevity :-)
	...
C Here's what this subroutine does to "go to" MAIN's 999
	RETURN 1
C Or, more generally, it could do
	GOTO 999
	...
999	RETURN 1	(assumes the * is the first such)
	END

Of course, not only are adding these alternate-returns and converting
FUNCTIONs to SUBROUTINEs annoying, but if you don't control the source
code for the intervening procedures, it might be impossible.

   (Which also prompts me to ask why the ENTRY statement is so frowned upon 
   that it is now deprecated?  Is it superceded by something else?)

Well, perhaps among other things I can't think of right now, ENTRY means to do
the following (numbers for identification only):

1.  Share code among different procedures for easier maintenance

2.  Persuade the compiler to produce less code for a given set of procedures,
    unless the compiler happens to "explode" all the entry point anyway (i.e.
    this is a "weak" reason in the sense that the standard says nothing about
    obeying it)

3.  Share non-COMMON data among different procedures

Other reasons that are really combinations of the above:

A)  Provide more than one name for a given procedure, as in a library
    (really #s 1 and 2, and perhaps 3 as well if it involves SAVEd data)

B)  For a number of similar procedures, reduce the need to retype lots of
    identical declarations (really #1)

Perhps others can add more reasons (perhaps I can immediately after
posting this :-), but I'll pretend for now that the above list is
definitive.

Fortran 90 addresses #3, which is really the only "functional" use for ENTRY
from a programming point of view.  Memory availability has made #2 kind of
less important.  #1 can be solved via Fortran-90's INCLUDE facility, better
program-development tools, and so on.

ENTRY is one of many examples of features in languages like Fortran and C
where the feature really is thought of as enabling several different
"primitive" features at once, even though those primitive features might well
be orthagonal to each other.

So, when a "compound feature" like ENTRY has one or more of its major
"primitive" features like #3 replicated in what is felt to be a more
maintainable, less error-prone way as is the case with Fortran 90, the
compound feature often becomes deprecated.  This is especially true when
implementation of the compound feature by compiler people is not only
annoying but involves questions like "what does the programmer really mean
to do here? save coding space? that'll cost run time; code more conveniently?
then I can increase code-space usage and generate better code, as long as
I make sure non-COMMON data is shared?".  In GNU Fortran, for example, I
currently (sort of) save code space at the expense of run time (and, perhaps,
optimization as well), but I could fairly easily (with a few days work,
perhaps) reverse that approach.

Sometimes, of course, once one of the primitive features is reimplemented
in a better way and that way gets used a lot, then rather than the older
compound feature like ENTRY becoming obsolete/deprecated, it actually takes
on a clearer meaning.

E.g., once most Fortran programs use MODULE or other Fortran-90 techniques
to do #3 (share non-COMMON data among procedures), then when ENTRY is seen,
it's pretty certain the programmer intended #1 or #2 -- in this case, still
a difficult choice for the compiler without guidance.  Further, if most
programs use INCLUDE or CASE techniques to achieve #1, then ENTRY will
finally mean pretty much just this: "share code to save code space even
at the expense of slower run time".  At that point, though ENTRY will still
be semantically a compound feature, it'll be practically _more_ useful
and directed in its everyday meaning and use.

So, I don't think of ENTRY (and other such features) as a compound feature
finally ready to be put out to pasture so much as a currently inscrutable
compound feature that might someday become, in practice, a fairly direct
way to accomplish a particular goal.

Other similar examples of compound features are SAVE (controls, potentially,
several implementation aspects) and C's "static" keyword as applied to local
variables (similar to Fortran's SAVE in a way).  In both cases they have
definite semantic meaning for the running program but also are informally
yet practically used to control placement of variables/arrays in memory,
even though the two things are potentially orthagonal (assuming a
reasonably sophisticated compiler).  For example, one might want an array
to be automatic (not static) in the sense of having one instance per
activation of the owning procedure, but have it be allocated from the heap
instead of the stack due to its size, or allocated in static memory (with
mechanisms to "stack" still-active instances somewhere, like the heap or
the stack) so there's always room for one set aside by the linker and/or
to speed up access to it on, say, a machine that does global access
faster than stack/heap access.

Language design is wonderful.
--

James Craig Burley, Software Craftsperson    burley@gnu.ai.mit.edu
Member of the League for Programming Freedom (LPF) lpf@uunet.uu.net
Newsgroups: comp.lang.fortran