Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!bellcore!decvax!decwrl!amdcad!lll-crg!topaz!bentley!kwh From: kwh@bentley.UUCP (KW Heuer) Newsgroups: net.lang.c Subject: Re: What happened to labels Message-ID: <638@bentley.UUCP> Date: Fri, 14-Mar-86 18:15:59 EST Article-I.D.: bentley.638 Posted: Fri Mar 14 18:15:59 1986 Date-Received: Sun, 16-Mar-86 10:36:28 EST References: <1420@brl-smok.UUCP>, <1700005@umn-cs.UUCP> Organization: AT&T Bell Laboratories, Liberty Corner Lines: 42 In article <1700005@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.