Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting drawn into the dubious world of goto spagetification!

Status
Not open for further replies.

phantompickler

Programmer
Mar 26, 2008
2
GB
The title says it all but im not sure if it is me at fault or just part of the fortran parcel!

Fortran seems to promote the use of gotos and they appear to be unavoidable if meaningful errors are to be extracted from intrinsic procedures. But it's like a bug: initially i thought 'i'll just use them where needed', but now having only just completed the data declarations and command-line parsing procedure for my first fortran program, i have realised that my code is already peppered with the pesky things!

I have even found myself using them like this (since axed):
100 errormsg = "A banner"
110 print *, errormsg, "usage: blah blah"

I have tended to stuff as much of the procedure's error handling as possible under the return statement, which has lead to fragmentation, as i realise that a labelled bit of code lurking in the bottom of my routine or elsewhere will satisfy a local demand; now i have things like this going on:

20 if(i < 0) then
errormsg = 'missing option argument: -' // param
goto 110
endif
execution jumps to to one labelled statement (20) from two branches, to check the index and assign a common error msg, then it's off to another to print it... but it gets worse: the if statement is duplicated in one location (the label would be better on the assignment statement but that would put it in another block. This kind of thing does not seem good, and i can foresee trouble ahead on this road)

and:
if(iDelim > 0)then
read(buffer:)iDelim-1), '(f5.2)', ERR=10) weiShape
read(buffer(iDelim+1:), '(f5.2)', ERR=10) weiScale
cycle
end if
10 errormsg = 'invalid weibull parameters argument: ' &
// buffer
goto 110

Check the tangled mess of goto branches and peddling like mad to avoid falling into it, should everything be ok!

goto 110 doesnt mean alot, even to the programmer that wrote it, except that things over 100 are generally hang around after the return statement and things below 100, before it - I guess things above 900 would be on the floor outside somewhere! Also, with numerical labels, comes the problem of maintaining their order. What to do if, a labelled statement needs to be inserted between 10 and 20, and 30, 40 and 50 are already defined? Break the sequence by sticking a 15 in there? Or break their order by making it 60? Or make it 20 and add 10 to all subsequent labels and references? I guess the first is the most sane option, until, of course, integers run out and then all thats left is rationals - which brings us right back to insanity again!

Im not sure whats going on... is this all normal or am i just on a binge after too much C'ness.

As a newbie, i have found a soft-spot for Fortran, but what's the deal with the length attribute of the almost scalar, but mostly not array, character datatype? I have the varying_string module but, as far as i can tell, in order to use it with any intrinsic procedure, it must first be copied to a static-length character?

This post was going to be a question but wound up as just a carboard cut-out type communication of my early experiences with fortran, I guess, in the hope that it may recieve some wisened reflection from seasoned fortraniers out there.

cya!
 
What form of pasta do you like: spaghetti or lasagne. They are both equally difficult to follow. On lasagne code, a minor distraction and you've completely lost your place and have to start all over again.

Also depends on which version of Fortran you're using. If you're using FI, FII or FIV, gotos are unavoidable.
F77, F90, F95 and F2003 have some constructs to get round loops, break out of loops, and replace computed gotos with cases.

The problem is you still need them in error handling like

read (10, end=100, err=200) xyz

end=100 is the same as a goto on end of file. In the example you've given, you can only avoid using a goto if you call an error handler that terminates the program.

Basically, gotos are unavoidable in any language if you want proper exception handling. try-catch is just another form of goto without using the same words. I use it in places where they insist they do not want to see the words goto. setjmp/longjmp is also the same thing. While loops and breaks are also the same thing. In fact, it is sometimes clearer to use a goto than to avoid using one with tons of flags.
 
haha, im not sure, but lasagne certainly sounds more appetising!

Actually after writing the post i reviewed the subroutine and have got rid of all of the gotos, excluding the error handlers. For each goto/label construct, i just needed to ask myself: what is this goto trying to achieve? And what are it's benefits (in terms of both efficiency and readability) over other constructs that would provide the same functionality? In each case it resulted in a nay!

While i guess gotos incurr less overhead than procedures, particularly if they involve passing large amounts of data, it is probably generally better to sacrafice the few extra cycles for the sake of readability.

I never even realised it, the try-catch thing that is... very sly!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top