Re: FORSTY - The Fortran Styler :-)
- From: dpb <none@xxxxxxx>
- Date: Sat, 02 Apr 2011 18:50:09 -0500
On 4/2/2011 5:09 PM, Richard Maine wrote:
Daniel Carrera<daniel@xxxxxxxxx> wrote:
On 04/02/2011 10:12 PM, Ron Shepard wrote:In article<in7inn$gas$1@xxxxxxxxxxxxxxxxx>, dpb<none@xxxxxxx>
wrote:
A typical use for GOTO is when you have numerous error checks
scattered around a subroutine, but for each one you want to do the
same kind of cleanup before returning an error code (sometimes
optionally, as described in my other post). The IF()GOTO is the
cleanest way to do this. In fact, there really isn't any other nice
way to do it, and the alternatives look pretty ugly IMO.
...check input arguments...
if(error)GOTO 9999
...do some work...
if(error)GOTO 9999
...do some more work...
if(error)GOTO 9999
return ! normal exit
What's wrong with a subroutine call?
...check input arguments...
if(error) call terminate()
Many, many things. If all you want to do is terminate, than that's fine.
I've got a subroutine like that. Mine is called error_halt and takes a
message string as an argument.
The subroutine call doesn't work nearly so well when you want to do
something *OTHER* than just terminate. That's very often the case in my
programs. Maybe you want to try something different instead, possibly
asking the user for revised data of some sort. Maybe you want to mark
that data point as failed and go on to the next. Whatever. Error
handling is sometimes more general than just error termination. The
bigger the codes get, the more important it can be to actually handle
some classes of errors instead of just punting.
A subroutine call can't return multiple levels, so at the very least,
you end up needing things like
if (error) then
call the_subroutine(arguments)
return
end if
Plus, very often the cleanup involves local variables that aren't going
to be available to some general-purpose subroutine. I'm likely to want
to do things like deallocate storage, close files, and other work.
Of course, you *CAN* get by without the goto. That's been proven. But it
gets to be a quite a mess. Ron's example above doesn't catch all the
fairly common complications because all his tests are at the same level
of structure. Picture something more like
....check input arguments
if (error) goto 9999
time_loop: do
... read some data
if (error) goto 9999
if (some_condition)
.... do some work
if (error) goto 9999
... do some more work
else
... do some different work
if (error) goto 9999
... more
end if
...
end do time_loop
That's exits from 3 different nesting levels. Not particularly rare.
I've seen more than that. Try to do this without the goto and it becomes
a mess.
I think I recall once arguing with the F folk about that one. They made
a suggestion that I agree would work without goto. But I also think it
an excellent example of knee-jerk reaction to the word goto, without
fixing any actual problems. In fact, it added extra problems.
You artifically put a loop around all the executable code in the
subroutine. You do this not because you actually ever intend it to loop,
but just because Fortran has a loop exit construct. Because you don't
actually want it to loop, you have to remember to put an exit at the end
or do something else artificial to keep the loop from actualy looping.
Then you can change all the goto's into exit statements as in
the_whole_enchilada: do
.... the body of the subroutine, including as many cases of
if (error) exit the_whole_enchilada
... as are needed
exit the_whole_enchilada !-- Don't forget this unconditional one.
end do the_whole_enchilada
if (error) then
... error cleanup stuff goes here
end if
That's one of the kinds of things I flatly refused to do. All the EXIT
statements are nothing but GOTO spelled slightly differently. They have
the minor improvement of using a name instead of a number, but that's
pretty trivial, particularly insomuch as it is the only statement number
in almost any of my code.
It adds a completely artificial DO block that has nothing to do with the
logical structure of the code. For example, the start of the DO block
has no significance; it just has to be anywhere before the first exit.
It is prone to the error of forgetting the final unconditional exit.
Just yuck. But at that, it is still better than what you would get from
some other so-called "structured" recodings.
Indeed...the error exits in the sample code _NEVER_ occur unless there's a major foobar somewhere in the database or the OS or hardware so those are plain vanilla aborting before getting started 'cuz there's no hope for the wicked here; we can't even kick it off.
I won't try to extract the actual computational model error recovery stuff; it's everything outlined above as for what it tries to recover and more and uses longjmp() besides per glenn's prescient posting. :)
(But, it rarely dies--afaik they've not had an unwanted shutdown from the workstation end since I retired after the conversion to NT in '99/'00 and it's been running on a dozen units 24/7 since.)
I was wishing I'd not left any of the error exits at all and left only the logic ones; they were what I was really pointing at as to where it makes simpler source w/o the loop structure to try to fold stuff into, that error handling really is too trivial to discuss.
--
.
- Follow-Ups:
- Re: FORSTY - The Fortran Styler :-)
- From: dpb
- Re: FORSTY - The Fortran Styler :-)
- References:
- FORSTY - The Fortran Styler :-)
- From: Daniel Carrera
- Re: FORSTY - The Fortran Styler :-)
- From: dpb
- Re: FORSTY - The Fortran Styler :-)
- From: Daniel Carrera
- Re: FORSTY - The Fortran Styler :-)
- From: dpb
- Re: FORSTY - The Fortran Styler :-)
- From: Ron Shepard
- Re: FORSTY - The Fortran Styler :-)
- From: Daniel Carrera
- Re: FORSTY - The Fortran Styler :-)
- From: Richard Maine
- FORSTY - The Fortran Styler :-)
- Prev by Date: Re: FORSTY - The Fortran Styler :-)
- Next by Date: Re: detecting end of a direct access file
- Previous by thread: Re: FORSTY - The Fortran Styler :-)
- Next by thread: Re: FORSTY - The Fortran Styler :-)
- Index(es):
Relevant Pages
|