Thanks
jcha...@netcom.com
Northrop Advanced Technology and Design Center
Pico Rivera, California
--
John H. Chauvin jcha...@netcom.COM
Netcom - Online Communication Services San Jose, CA
John> Is it possible to transfer control from a nested subroutine directly to the
John> main routine without have to execute multiple returns from all the
John> subroutines in between? I would like a way of exiting directly to the main
John> routine when a error is detected six or seven subroutines down.
I would be interested too. I don't think that there is an easier way than
doing
.
.
call a
if (topmost) return
.
.
(where `topmost' is set to .true. within `a') for all subsequent calling
routines.
Larry
Write a subroutine to do whatever final cleanup is needed. Have
the main program end with a call to the cleanup routine. Have the
cleanup routine finish with a STOP statement, so that it never
returns to the main program.
Now, when an error is detected and you want to bail out, you can
just call the cleanup routine, knowing it will never return. You
can even have the routine take an error argument to indicate the
reason for termination, and have the cleanup take appropriate
action.
--
Dave Seaman
a...@seaman.cc.purdue.edu
No, you cannot; but executing the multiple returns can be simplifed by
the adoption of the alternate return dummy parameter for the use of
error handling. (The sole use, preferably.)
-P.
--
************************f*u*cn*rd*ths*u*cn*gt*a*gd*jb*************************
Peter S. Shenkin she...@still3.chem.columbia.edu Columbia Univ., Chemistry
********* DEMOCRACY: The theory that the people know what they want, ********
********** and deserve to get it good and hard. -- H. L. Mencken ************
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, ..?
(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?)
--
+------------------------------------------------------------------------------+
Michael Page, Maths Dept, Monash University, Clayton, Victoria, AUSTRALIA 3168
email: m...@hal.maths.monash.edu.au phone: +61 3 565 4486 FAX: +61 3 565 4403
+------------------------------------------------------------------------------+
Hmmmm ... so do you think it is really possible to do something like
program main
1 continue
...
call level1(...)
...
stop
entry backtomain
* pretend we can 'restart' program
goto 1
end
subroutine level1(...)
...
call level2(...)
...
end
subroutine level2(...)
...
if (troubles) call backtomain
...
end
and 'fall' in 'backtomain' from level2 as many times as we want?
my guess is that this can be done but eats stack space because
no one ever returns. well actually it looks like a form of recursion,
where we do not need to retain data from previous calls, so
is this a form of pseudo-recursion allowed by Fortran?
--
Furio Ercolessi
Materials Research Laboratory | Intl School for Advanced Studies
Univ. of Illinois at Urbana-Champaign | Trieste, Italy
fu...@uiuc.edu | fu...@sissa.it
(a) Pass the data to each subroutine explicitly, as arguments; or, if this is
too clumsy or inefficient,
(b) Let the subroutines share the data via a well-documented COMMON block.
I understand that FORTRAN 90 allows you to group subroutines together into
"modules" which share the same data.
In situations where two subroutines share much of the same code, it's considered
better form to split off the common code into a separate subroutine, or maybe
put it in an INCLUDE file if your compiler allows it.
Jon Bell / Dept. of Physics & Comp. Sci. / Presbyterian College / Clinton SC USA
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 bur...@gnu.ai.mit.edu
Member of the League for Programming Freedom (LPF) l...@uunet.uu.net
Should I add a smiley?
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland
home: bovenover 215, 1025 jn amsterdam, nederland; e-mail: d...@cwi.nl