What happened to labels
KW Heuer
kwh at bentley.UUCP
Sat Mar 15 09:15:59 AEST 1986
In article <1700005 at umn-cs.UUCP> umn-cs!herndon writes:
> When C started acquiring stricter types, no special label type
>was included for coercions or any other operations. Thus one
>cannot fill an array with labels to construct a jump table (even
>though this can not cause any type conflicts) nor can one have
>a variable of type label. Constraints that all variables of
>type label be initialized to a legitimate label, and that such
>variables must be local and may not be passed as parameters might
>cover the problems of goto's going to undefined locations. Jump
>tables are quite useful to those of us who write programs to
>generate C programs -- and we might happily observe such constraints.
It would be more in the "spirit of C" to not enforce those restrictions,
and let a branch to anything other than a label in the current function
be an undefined result. This might be useful for sufficiently esoteric
applications (under #ifdef, of course), and lint might be able to catch
the violations.
I think someone already said how to simulate arrays of label pointers,
but let's be explicit here. I assume that the only legal operations
on a label are branch and address-of, just as with a function. So we
can take any program that uses labels and replace the type "label *"
(plain "label" is as useless as plain function, "void ()") with the
datatype "enum label", and replace any label constants x (other than in
goto statements) with LAB_x. Define enum label to contain all such
LAB_x.
Now if p was of type "label *" (so it is now a "enum label"), replace
"goto *p" with "switch (p) { case LAB_x: goto x; ... }". Note that p
can be any expression.
I would hope that any good optimizer would convert the switch into a
jump table; there is some inefficiency introduced by the switch (one
extra table lookup, plus the "unnecessary" check for the default),
but I would think it would be tolerable.
I don't recall that anyone has mentioned it, but one neat use for a
label variable (other than in generated code) is to emulate coroutines.
I've seen some of Doug McIlroy's code that did this (using int/switch;
enum hadn't been invented). I have a program of my own that uses a
coroutine, but since there's only one pseudo-label (besides the entry
point) so I just used a CalledBefore flag.
More information about the Comp.lang.c
mailing list