brianc@cognos.UUCP (Brian Campbell) (02/23/87)
Why are labelled loops not supported in ANSI C? I think the reasoning for not including them was something to the effect "they're too much like goto's". This seems a rather weak objection -- the work-around *is* a goto, or superfluous condition testing. Does anyone have some more information on why such a useful feature (in my opinion) would be omitted? - Brian Campbell
franka@mntgfx.UUCP (02/27/87)
In article <388@cognos.UUCP> brianc@cognos.UUCP (Brian Campbell) writes: > > Why are labelled loops not supported in ANSI C? > Does anyone have some more information on why such a useful feature >(in my opinion) would be omitted? > > - Brian Campbell Probably because there IS a workaround for this feature which is seldom used. Now for my pet peeve. Why can't you take the address of a label? This would be useful in writing threaded code interpreters and in doing high performance code. As far as I know, there is no work around for this problem. E.g., label *jump_table[] = { &exe_seg_0, &exe_seg_1, ... }; while (!halt_flag) { /* do something to load the byte code */ goto *jump_table[byte_code]; exe_seg_0: /* stuff */ continue; exe_seg_1: /* stuff */ continue; } I know that some of you will be saying how is this different than a switch statement? It is different in three ways 1) A switch statement will often be converted to a series of if-then-else on many machines. With this method, I have control over how the code is executed. I also control range checking. 2) I can convert the byte codes for an interpreted language into addresses of the actual routines at load time (can you say direct threaded code, boys and girls?), so that the array lookup of the above is unnecessary. This also avoids the routine call overhead which is the closest way to do this in C currently. 3) It allows me to dynamically construct code in an array an execute it without resorting to assembly code linkages (this is very important for doing incremental compiling / bytecode conversion easily). This construct is not difficult to implement on linkers, it is not any more hazardous than the goto statement itself, and it introduces a capability into the language which is not currently there and for which no fast workaround exists. In fact, I wonder why this idea has not been implemented before... Frank Adrian Mentor Graphics, Inc. These opinions are my own. Don't blame my employer.
herndon@umn-cs.UUCP (03/02/87)
>In article <388@cognos.UUCP> brianc@cognos.UUCP (Brian Campbell) writes: > Why are labelled loops not supported in ANSI C? >>/* Written 7:17 pm Feb 87, 19783 by mntgfx!franka in umn-cs:comp.lang.c */ >> >>Now for my pet peeve. Why can't you take the address of a label? ... >> label *jump_table[] = { &exe_seg_0, &exe_seg_1, ... }; >>... justifications for this ... >...... In fact, I wonder why this idea has not been implemented before... >Frank Adrian >Mentor Graphics, Inc. In fact, this *used* to be legal, and has been done. In days of old (when knights were *ahem*) labels had type (int *). Thus a programmer could quite easily load an array full of label values and happily goto <expr>. It peeves me greatly too, since I would like to maintain my own call stack for a threaded interpreter; allowing the C compiler to maintain it will cost me >>10 times the space. (I can code the info needed to save and restore my environments in less than 2 bytes; the stacks may grow very deep: ~= 100K procedure calls.) Since I can't use arrays of labels, I either: 1) Have to use a machine dependent hack for jumping to the code 2) Have to maintain the stack myself, iteratively calling procedures which do what I want, while passing add'l call/return info with the calls and returns, costing me the time of the procedure call and return, and forcing me to generate useless prologue/epilogue code for each procedure. The former prohibits me from uniformly mixing dynamically generated and statically compiled code. The latter uglifies code generation and costs time (procedure overhead) and space (code) performance.
john@viper.UUCP (03/02/87)
Frank, I -really- like the idea of being able to find the address of a label. There is only one problem I can think of.... You have to come up with a construct for doing an indirect goto... Your example gives a good answer to this... Your solution gives an answer which is consistant with all known (known by me anyway) implementations, corrects a minor inconsistancy in the general semantics of the language (if you can do it with functions, then -why-not- labels too?), and is easily implemented on all machines I know of (more than 30). There are several potential programming situations where I could see a real use for this capability and would like to hear a response on this from any members of the ANSI committiee on C. --- John Stanley (john@viper.UUCP) Software Consultant - DynaSoft Systems UUCP: ...{amdahl,ihnp4,rutgers}!{meccts,dayton}!viper!john
henry@utzoo.UUCP (Henry Spencer) (03/03/87)
> Why are labelled loops not supported in ANSI C? I think the reasoning > for not including them was something to the effect "they're too much > like goto's"... Actually, more probably the reasoning for not including them was "since nobody has ever implemented this in a C compiler, there is no operational experience with it *in* *C* to determine how useful it is and whether it interacts badly with other constructs; since there is no desperate need for it, the lack of real experience is sufficient reason not to do it". -- "We must choose: the stars or Henry Spencer @ U of Toronto Zoology the dust. Which shall it be?" {allegra,ihnp4,decvax,pyramid}!utzoo!henry
adb@elrond.UUCP (Alan D. Brunelle) (03/06/87)
In article <545@mntgfx.MENTOR.COM>, franka@mntgfx.MENTOR.COM (Frank A. Adrian) writes: > Now for my pet peeve. Why can't you take the address of a label? This > would be useful in writing threaded code interpreters and in doing high > performance code. As far as I know, there is no work around for this > problem. E.g., > label *jump_table[] = { &exe_seg_0, &exe_seg_1, ... }; > while (!halt_flag) { > /* do something to load the byte code */ > goto *jump_table[byte_code]; > exe_seg_0: > /* stuff */ > continue; ... > > I know that some of you will be saying how is this different than a switch > statement? It is different in three ways > 1) A switch statement will often be converted to a series of if-then-else > on many machines. With this method, I have control over how the code is > executed. I also control range checking. > 2) I can convert the byte codes for an interpreted language into addresses > of the actual routines at load time (can you say direct threaded code, boys > and girls?), so that the array lookup of the above is unnecessary. This also > avoids the routine call overhead which is the closest way to do this in C > currently. > 3) It allows me to dynamically construct code in an array an execute it > without resorting to assembly code linkages (this is very important for > doing incremental compiling / bytecode conversion easily). > This construct is not difficult to implement on linkers, it is not any more > hazardous than the goto statement itself, and it introduces a capability into > the language which is not currently there and for which no fast workaround > exists. In fact, I wonder why this idea has not been implemented before... > Would it not be better to use what C already offers? How about implementing this with routines rather than goto's? If you declare an array of pointers to functions, then when you have your byte_code then: (*func)[byte_code](params); will do exactly what your want with the added overhead of a procedure call. (DON'T flame me on the syntax - look it up....) These arrays can be built sort of dynamically (remember if you have a function foo, then &foo is a sort of constant (decided and link/load time)), and it is very clear what is going on...I have used this technique many times (Ever simulate a M68000? break the 32 bit instructions down into small 2 to 4 bit patterns, then use the above to call a routine to further break it down...) al /-------------------------------------------------------------------------\ | | | Alan D. Brunelle | | | | uucp: ...decvax!elrond!adb "To do all the talking and not | | phone: (603) 885-8145 to be willing to hear anything | | us mail: Calcomp/Lockheed DPD is greediness." | | (PTP2-2D01) Democritus | | Hudson NH 03051-0908 | | | \-------------------------------------------------------------------------/
chris@mimsy.UUCP (Chris Torek) (03/08/87)
:In article <545@mntgfx.MENTOR.COM>, franka@mntgfx.MENTOR.COM (Frank A. Adrian) writes: :>[Jump tables] would be useful in writing threaded code interpreters :>and in doing high performance code. In article <674@elrond.UUCP>, adb@elrond.UUCP (Alan D. Brunelle) writes: >Would it not be better to use what C already offers? How about implementing >this with routines rather than goto's? This may be unacceptably slow. >If you declare an array of pointers to functions, then when you have >your byte_code then: > >(*func)[byte_code](params); > >will do exactly what your want with the added overhead of a procedure >call. (DON'T flame me on the syntax - look it up....) And look it up again! It is (*table[code])(param). If function call overhead is not a problem, this works very well for driving state transition based actions too. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu