[net.lang.c] What happened to label variables?

dietz%slb-doll.csnet@CSNET-RELAY.ARPA (Paul Dietz) (03/01/86)

I recall that C on early UNIX's treated labels as constants of type
(int *).  As a result, you could assign labels to variables and even
jump to the label in a variable.  This got taken out of K&R, and
as I far as I can tell it's not in other C's today.

This is unfortunate; I ran into a situation recently in which I wanted
to (automatically) generate C code that should, for efficiency reasons,
contain label variables.  I had to simulate them with a switch statement
of the form:

	switch(labelindex) {
		case 1: goto label1;
		case 2: goto label2;
		...
		case n: goto labeln;
		default: fprintf(stderr,"unknown label index: %d\n",
					labelindex);
			 abort();
	}

This is a lot slower, though, and some of the compiler's I tried it
on (the VAX VMS C compiler, for example) did not peephole optimize the
jump table implementing the switch and the branch instructions
implementing the goto's (this should have been treated as a jump
to a jump).

I'm curious if any commerically available C compilers implement jumps
to arbitrary pointers without recourse to assembly language inserts.

dietz%slb-doll.csnet@CSNET-RELAY.ARPA (Paul Dietz) (03/02/86)

>> [the lack of label varibles in C] is unfortunate...

>I don't think you will get much sympathy on this point.

I certainly wasn't suggesting the use of label variables by human
programmers.  However, like gotos, they make writing
source-to-source translators easier in some cases (such as
mine).

You suggested:

> 	switch(labelindex) {
> 		case 1: label1: <code> break;
> 		case 2: label2: <code> break;
> 		...
> 		case n: labeln:	<code> break;
> 		default: fprintf(stderr,"unknown label index: %d\n",
> 					labelindex);
> 			 abort();
> 	}

Unfortunately, this doesn't always work.  Some of the label1 ... labeln may be
inside additional switch statements.  In any case, using a switch statement is
still slower than a jump to a label variable, since the object code must
check if the index is out of range (the VAX does this in microcode but
it's still slower than a jump).

>> [Do any current compilers have indirect jumps...?]
> Probably not. I think they all wised up. Why don't you?

Because I want to generate C, and I want efficient code.  The switch
hack is contorted and inefficient.

ka@hropus.UUCP (Kenneth Almquist) (03/07/86)

> I recall that C on early UNIX's treated labels as constants of type
> (int *).  As a result, you could assign labels to variables and even
> jump to the label in a variable.  This got taken out of K&R, and
> as I far as I can tell it's not in other C's today.

Reasons for removing label variables from C include:

1)  The forward reference problem.  Let's say you have C code that goes

		p = l;
		...
	l:

When the compiler sees the assignment, "l" has not been declared.  The
solution used when C had label variables was to make all undeclared
variables default to type "label".  The problem comes when you forget
to declare "p".  The C compiler would default "p" to type label, notice
that you were attempting to assign to a variable of type label, and
complain "lvalue required."  Hardly the ideal error message.

2)  Portability.  On some machines pointers to different types of
objects are different.  Insisting that label pointers and integer
pointers be the same type clearly limited the portability of C.

3)  Lack of use.  As far as I know, no one ever actually used label
variables in C.  The editor once jumped to the routine "error" rather
than calling it.  This trick saved two bytes of stack space, a trivial
amount of execution time, and was nonportable.  (The VAX has a special
header on functions; you cannot simply jump to the first byte of a
subroutine even if that routine always calls longjmp rather than
returning.)  Clearly, this use would have been eliminated even if C had
not been changed to prohibit it.  I believe that using label variables
is invariably bad style...

> This is unfortunate; I ran into a situation recently in which I wanted
> to (automatically) generate C code that should, for efficiency reasons,
> contain label variables.  I had to simulate them with a switch statement
> [.....]

...although style is not important in machine generated code.  Still,
the language should concentrate on features that will be used with some
regularity.

> This is a lot slower, though, and some of the compiler's I tried it
> on (the VAX VMS C compiler, for example) did not peephole optimize the
> jump table implementing the switch and the branch instructions
> implementing the goto's (this should have been treated as a jump
> to a jump).
> 
> I'm curious if any commerically available C compilers implement jumps
> to arbitrary pointers without recourse to assembly language inserts.

If you do find such a compiler, you will be giving up portability.  If
you can afford that, you should consider generating assembly code; it
will compile and execute faster.

I *can* point you to many commercially available C compilers that do
peephole optimization of the jump table implementing a switch; most C
compilers written at Bell Laboratories will do this.
				Kenneth Almquist
				ihnp4!houxm!hropus!ka	(official name)
				ihnp4!opus!ka		(shorter path)