chris@mimsy.UUCP (Chris Torek) (06/29/88)
In article <1544@microsoft.UUCP> bobal@microsoft.UUCP (Bob Allison) writes: >reading [a previous] article I did manage to come up with a feature >which is fairly difficult to implement in C: assigned gotos. I don't >believe C can take the address of a label ... (Some compilers allow it, but that is just a bug.) I am confident that I could convert any assigned GOTO FORTRAN code into something more reasonable, but I am curious: what do people actually use it for? I once did some fairly extensive FORTRAN programming (the alterative was BASIC, without local variables, etc); the only thing I used ASSIGN statements for was to bypass the FORTRAN system to get addresses into arguments to assembly coded support routines. This is, of course, not legal FORTRAN, just useful. (I was emulating IBM's extension where one can say CALL FOO(param, &label1, &label2) ... SUBROUTINE FOO(param, *, *) ... C I forget the exact syntax, but... jump to label1: RETURN 1 END -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
kurtk@tekcae.TEK.COM (Kurt Krueger) (07/01/88)
Another mis-use of assigned GOTO takes into account that most implementations use the actual address of the label and don't bother to check against the list of possible branches that is required for the GOTO LABEL, (100,300) statement. If you pass LABEL to a subroutine or put it in common, you can branch from one subroutine directly into another. (!)
dik@cwi.nl (Dik T. Winter) (07/03/88)
In article <1821@tekcae.TEK.COM> kurtk@tekcae.UUCP (Kurt Krueger) writes: > Another mis-use of assigned GOTO takes into account that most implementations > use the actual address of the label and don't bother to check against the list > of possible branches that is required for the GOTO LABEL, (100,300) statement. > If you pass LABEL to a subroutine or put it in common, you can branch from > one subroutine directly into another. (!) Yes, but most likely, the routine you jump to is not able to access its parameters. (This happens if the parameter list address is stored in a register.) -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
nmm@cl.cam.ac.uk (Nick Maclaren) (07/04/88)
In article 766, chris@mimsy.UUCP (Chris Torek) writes: > I am confident that I could convert any assigned GOTO FORTRAN code into > something more reasonable, but I am curious: what do people actually > use it for? ... In general, I agree, but there are a few algorithms where assigned GOTOs clarify the code (sic). The ones I have written were all simple finite state algorithms (e.g. contour plotting), where the next state to go to was a function of the previous state. That is, state n+1 is decided by state n-1, rather than state n. The 'structured' approach is a case statement inside an infinite loop; I find this rather less clear. Still, I would not preserve assigned GOTOs for the sake of a few unusual algorithms, and no longer use them myself (even in Fortran). Nick Maclaren University of Cambridge Computer Laboratory nmm@uk.ac.cam.cl
jerry@violet.berkeley.edu ( Jerry Berkman ) (07/06/88)
In article <1821@tekcae.TEK.COM> kurtk@tekcae.UUCP (Kurt Krueger) writes: >Another mis-use of assigned GOTO takes into account that most implementations >use the actual address of the label and don't bother to check against the list >of possible branches that is required for the GOTO LABEL, (100,300) statement. >If you pass LABEL to a subroutine or put it in common, you can branch from >one subroutine directly into another. (!) According to the 1977 standard, p.11-2, the list is optional, not required. However: "If the parenthesized list is present, the statement label assigned to i must be one of the statement labels in the list." and branching between routines is not allowed: "the variable i must be defined with the value of a statement label of an executable statement that appears in the same program unit". Although part of the standard, assigned GO TOs should be avoided. - Jerry Berkman U.C. Berkeley, jerry@violet.berkeley.edu
ssd@sugar.UUCP (Scott Denham) (07/07/88)
In article <12215@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > I am confident that I could convert any assigned GOTO FORTRAN code into > something more reasonable, but I am curious: what do people actually > use it for? { one example of such use deleted} > In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) One of the few helpful uses I've made of assigned GOTO is to implement a form of internal procedures - for small chunks of code that can't be handled as statement function definitions but need access to too much stuff to make a reasonable subroutine out of it. (Subroutine calls also break optimization pretty badly on IBM, or did at one time). Such use might look something like ASSIGN 1400 TO R1 GOTO 10020 1400 CONTINUE ....... 10200 FOO = FOO ** 2 ....... GOTO R1 (1400,1500,1600,1700) Unfortunately, IBM's compiler does no checking whatsoever of the possible return values - at one time they didn't even have to be valid labels!! This can lead to some rather misleading documention. Are other compilers as loose with the defintions ??? Scott Denham Western Atlas International
ags@s.cc.purdue.edu (Dave Seaman) (07/07/88)
In article <2261@sugar.UUCP> ssd@sugar.UUCP (Scott Denham) writes: >Such use might look something like > ASSIGN 1400 TO R1 > GOTO 10020 > 1400 CONTINUE > ....... > 10200 FOO = FOO ** 2 > ....... > GOTO R1 (1400,1500,1600,1700) > Unfortunately, IBM's compiler does no checking whatsoever of the possible > return values - at one time they didn't even have to be valid labels!! > This can lead to some rather misleading documention. Are other compilers > as loose with the defintions ??? The fact that a compiler does not check the return values does not necessarily mean that it is safe to put in anything you like. An optimizing compiler may assume (without bothering to check) that your list of return values is accurate and use that assumption to generate more efficient code. Naturally, such code is likely to break if the destination of the GOTO is not in the label list. I have actually seen this happen with CDC's old FTN compiler. The program worked with optimization turned off, but bombed with optimization on. -- Dave Seaman ags@j.cc.purdue.edu
jackson@esosun.UUCP (Jerry Jackson) (07/08/88)
Someone asked for uses for the assigned goto. Until this discussion, I did not know Fortran had such a beast. However, I know of an application where I would dearly have loved to have it. (I'm mostly a Lisp/C hacker..) I wrote a Scheme interpreter in 'C'. One of the properties of Scheme is that procedure calls MUST be tail recursive -- hence, the 'C' function calling mechanism was not applicable to Scheme function calls. What I had to do was simulate a procedure call/return sequence. To do this right, you have to be able to push return addresses (i.e. labels) on an explicit stack, then pop them and goto the result. C does not allow you to 'goto' the value of a variable -- If it did, I could have written a much more efficient interpreter. I would have liked to have written: pop(ReturnAddress); goto ReturnAddress; Instead, I had to use a giant switch statement on tags that looked like: pop(ReturnAddress); switch (ReturnAddress) { case APPLY: code for apply...; case XXXX: code for XXXX...; . . . } I spent much time cursing 'C' for not having an assigned goto. +-----------------------------------------------------------------------------+ | Jerry Jackson UUCP: seismo!esosun!jackson | | Geophysics Division, MS/22 ARPA: esosun!jackson@seismo.css.gov | | SAIC SOUND: (619)458-4924 | | 10210 Campus Point Drive | | San Diego, CA 92121 | +-----------------------------------------------------------------------------+
ssd@sugar.UUCP (Scott Denham) (07/08/88)
In article <3350@s.cc.purdue.edu>, ags@s.cc.purdue.edu (Dave Seaman) writes: (discussion and examples of computed GOTO's deleted) > > The fact that a compiler does not check the return values does not > necessarily mean that it is safe to put in anything you like. An > optimizing compiler may assume (without bothering to check) that your list > of return values is accurate and use that assumption to generate more > efficient code. Naturally, such code is likely to break if the > destination of the GOTO is not in the label list. > > Dave Seaman I certainly didn't mean to condone putting bogus values into the list of alternate branch points. As one who derives a large portion of my livelyhood out of trying to mantain, debug, and extend FORTRAN code written be other (soimetimes LOTS of other) people, I can testify that the only thing WORSE than undocumented code is MIS-documented code. No matter how much skepticism you view the documentation with, it tends to lead you to a particular mindset when trying to understand how a program does (or doesn't :} ) what it is supposed to do. Bogus lists of alternate returns from assigned GOTO's are one of the nastiest! (Did he REALLY tghink he could get there from here....here from there???!) Scott Denham
chris@mimsy.UUCP (Chris Torek) (07/08/88)
In article <222@esosun.UUCP> jackson@esosun.UUCP (Jerry Jackson) writes: >Someone asked for uses for the assigned goto. ... >I wrote a Scheme interpreter in 'C'. One of the properties of Scheme >is that procedure calls MUST be tail recursive -- hence, the 'C' >function calling mechanism was not applicable to Scheme function >calls. What I had to do was simulate a procedure call/return >sequence. To do this right, you have to be able to push return >addresses (i.e. labels) on an explicit stack, then pop them and goto >the result. C does not allow you to 'goto' the value of a variable -- >If it did, I could have written a much more efficient interpreter. On the other hand, FORTRAN does not allow this either: not the way you want it. The GOTO is only allowed to transfer control within the current module (program, subroutine, or function). It sometimes works to jump outside the function, but it is by no means required to work. You can almost do this with setjmp and longjmp in C. A better way is to do it in assembly: extern void foo(); ... bar() { ... jump_to(foo); } # jump_to, for vax: .globl _jump_to _jump_to:.word 0 movl 4(ap),12(fp) # stash new return pc ret # and away we go This version is somewhat simplistic; it assumes that bar() and foo() have the same register save mask, for instance. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
jackson@esosun.UUCP (Jerry Jackson) (07/08/88)
In article <12362@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: Path: esosun!seismo!uunet!lll-winken!lll-tis!ames!ncar!oddjob!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.fortran Date: 8 Jul 88 04:38:27 GMT References: <2742@utastro.UUCP> <20008@beta.UUCP> <224@raunvis.UUCP> <222@esosun.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 38 In article <222@esosun.UUCP> jackson@esosun.UUCP (Jerry Jackson) writes: >Someone asked for uses for the assigned goto. ... >I wrote a Scheme interpreter in 'C'. One of the properties of Scheme >is that procedure calls MUST be tail recursive -- hence, the 'C' >function calling mechanism was not applicable to Scheme function >calls. What I had to do was simulate a procedure call/return >sequence. To do this right, you have to be able to push return >addresses (i.e. labels) on an explicit stack, then pop them and goto >the result. C does not allow you to 'goto' the value of a variable -- >If it did, I could have written a much more efficient interpreter. On the other hand, FORTRAN does not allow this either: not the way you want it. The GOTO is only allowed to transfer control within the current module (program, subroutine, or function). It sometimes works to jump outside the function, but it is by no means required to work. You can almost do this with setjmp and longjmp in C. A better way is to do it in assembly: extern void foo(); ... bar() { ... jump_to(foo); } # jump_to, for vax: .globl _jump_to _jump_to:.word 0 movl 4(ap),12(fp) # stash new return pc ret # and away we go This version is somewhat simplistic; it assumes that bar() and foo() have the same register save mask, for instance. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris I don't know if this really requires a follow-up but, actually, the ability to jump to a label stored in a variable within the current function would have been enough to do what I wanted... Only Scheme special forms (mostly) would have required the goto's (primitive functions that do not call the evaluator need not be tail-recursive -- they will always return before evaluation continues anyway). The code for each of the special forms would just have to have been included in the main function for the interpreter. So, I would have had a large main function, but it would have been fast!!!! +-----------------------------------------------------------------------------+ | Jerry Jackson UUCP: seismo!esosun!jackson | | Geophysics Division, MS/22 ARPA: esosun!jackson@seismo.css.gov | | SAIC SOUND: (619)458-4924 | | 10210 Campus Point Drive | | San Diego, CA 92121 | +-----------------------------------------------------------------------------+
jlg@beta.lanl.gov (Jim Giles) (07/12/88)
In article <12362@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > [...] > You can almost do this with setjmp and longjmp in C. A better > way is to do it in assembly: > > # jump_to, for vax: > .globl _jump_to > _jump_to:.word 0 > movl 4(ap),12(fp) # stash new return pc > ret # and away we go > Think again. My machine doesn't have any of these mnemonics. I'm not even sure what the above code means. The requirement is for a PORTABLE way of doing the action. In this respect, a 'better way' would be to allow pointers to code, and allow jumps to them (you already can reference a code pointer for a procedure call). Note: this doesn't mean that I agree that the original poster had found a legitimate use of assigned GOTOs. I would have tried VERY hard to avoid his solution. But, if this method was indeed the most efficient, then assembly is not a good substitute to having the feature in the language. J. Giles Los Alamos
chris@mimsy.UUCP (Chris Torek) (07/12/88)
>In article <12362@mimsy.UUCP> I suggested doing `jump to another function without changing {stack frames / execution environments / whatever you want to call them}': >>do it in assembly: >> # jump_to, for vax: --- In article <20664@beta.lanl.gov> jlg@beta.lanl.gov (Jim Giles) writes: >Think again. My machine doesn't have any of these mnemonics. Are you deliberately being irritating? >... The requirement is for a PORTABLE way of doing the action. Not necessarily. >In this respect, a 'better way' would be to allow pointers to code, >and allow jumps to them .... Possibly so. But if you MUST use some language (perhaps it is the only one you have that is anywhere near suited to the task) and you cannot do something within that language, the best way is to do it out of that language---*AFTER* abstracting the operation, so that it can be done on other machines without too much effort. (Perhaps it will take a fair bit of effort; maybe the reason it is not in the language is because it is *hard* on some machines. The VAX version I wrote is basically wrong; a correct version is quite a bit longer.) >... But, if this method was indeed the >most efficient, then assembly is not a good substitute to having >the feature in the language. No, but changing the language to add it is also not a good substitute for having it in the language, unless you intend to convince everyone else also to change the language in the same way (and are willing to back off if the next ANSI or ISO or ... standard decides it should be done differently). (If it is your own language, of course, do whatever you like.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris