[comp.lang.c] X3J11: Why no labelled loops?

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