[net.lang.c] Using &LABEL

daemon@decwrl.UUCP (The devil himself) (08/30/84)

Using &LABEL___________________________________________________________________

> You can take the address of a label using "&foo".
> By the way, is there anything useful you can do with this feature?
> Use it as a function address?  Assigned goto's???  Something else?????

	Good question.  I never use goto's, so I never use labels.  (I may use
a goto someday, but so far I've never had to.)  I could imagine horrible things
like passing the address of a label to another function and executing a goto.
Anyone who does that should probably be strung up by their thumbs.

	VMS RMS has a system function, sys$open(), that takes three arguments:
(1) the address of a File Access Block (FAB), (2) the address of a user-written
error completion routine (optional), and (2) the address of a user-written suc-
cess completion routine (also optional).
	I thought I could use &LABEL to see if the "user-written routine" had
to be a function or just an entry-point, but VAX C doesn't allow use of &LABEL.
Perhaps someone out there running a different type of C on a VMS system could
try it.

	Finally, is &LABEL an officially sanctioned K&R construct?  I don't
have my copy with me so I can't look it up right now...
		<_Jym_>

:::::::::::::::: Jym Dyer
::::'  ::  `:::: Nashua, New Hampshire
::'    ::    `::
::     ::     :: DYER%VAXUUM.DEC@DECWRL.ARPA
::   .::::.   :: {allegra|decvax|ihnp4|ucbvax}!decwrl!dec-rhea!dec-vaxuum!dyer
::..:' :: `:..::
::::.  ::  .:::: Statements made in this article are my own; they might not
:::::::::::::::: reflect the views of |d|i|g|i|t|a|l| Equipment Corporation.

bet@ecsvax.UUCP (08/31/84)

This brings up my only *major* complaint with C -- the weakness of its
handling of labels. The question

>>	Finally, is &LABEL an officially sanctioned K&R construct?  I don't
>> have my copy with me so I can't look it up right now...

is pretty easy (I think): From the C Reference manual, in the back of
K&R, section 9.12:
	... The only use of a label is as a target of a goto. ...

(You can take my word that this isn't an unreasonably out-of-context
quote). Many compilers, however, as an accident of implementation, give
the address in the code space when you use &label, allow you to assign
that to a variable of suitable size (int often works) and branch to
it.  HOWEVER, this is flagrantly illegal and non-portable. The
definition of C prohibits it. So here goes my desired extention to C:

Make 'label' be a data type. Consider "<identifier> :" to be a
constant, allow label variables to be created, and in particular arrays
of labels.  Voila: jump tables! Many (most) uses of goto <label> might
be unstructured, or even UGLY. However, one particular construct occurs
reasonably often in a kind of programming C is good at: implementing
compilers and suchlike text processors. This construct is the finite
state automaton. What you really want to implement one efficiently is a
label array, for "goto array[input]" to be a state transition.

It seems to me that this treatment of "label" wouldn't conflict with the
existing definition of C, and in fact would formally bless a "feature"
that some compilers already have. I am grateful, at least, that the
philosophy in designing a C compiler is to make it do everything that C
requires, but not necessarily to prohibit everything C prohibits. LONG
LIVE LINT!!!
					Bennett Todd
					...{decvax,ihnp4,akgua}!mcnc!ecsvax!bet

andrew@orca.UUCP (Andrew Klossner) (08/31/84)

[]

	"I could imagine horrible things like passing the address of a
	label to another function and executing a goto."

From K&R:

	"Control may be transferred unconditionally by means of the
	statement

		goto identifier;

	The identifier must be a label located in the current function."

Thus, no "goto parameter".

Back in my youth, I remember wading through a good deal of v6 code
which used "signal(2,&label)" to transfer control within the procedure
on receipt of control-C.  This sort of thing seems to have died out.

  -- Andrew Klossner   (decvax!tektronix!orca!andrew)      [UUCP]
                       (orca!andrew.tektronix@rand-relay)  [ARPA]

jack@rlgvax.UUCP (Jack Waugh) (09/03/84)

As I recall (for what it's worth now), the C Reference that came
with Fifth Edition UNIX (the version before V6) suggested using
integer pointers as label variables.

K&R, page 204, section 9.12, says "the only use of a label is
as a target of a goto".

ark@rabbit.UUCP (Andrew Koenig) (09/05/84)

Bennett Todd suggests that arrays of labels might be useful
for jump tables.  That's exactly the purpose of the
switch statement.

jack@vu44.UUCP (09/13/84)

[Bug Bug Bug, Bug is the word......]

Well, never a dull moment when you play around with your C compiler.
With the V7 compiler, the following piece of code not only
compiles correctly, it even *works*. How long will it be before we
get rid of fortrisms and the like???
----------------------------------
#include <stdio.h>

main() {

    func(0);
    func(1);
}

func(arg) int arg;
{

int *jumptab[2];

    goto endofit; /* cannot use &label before it's defined */
lab0:
    printf("Lab 0\n");
    return;
lab1:
    printf("Lab 1\n");
    return;
endofit:
    jumptab[0] = &lab0;
    jumptab[1] = &lab1;
    goto jumptab[arg];
}
---------------------

	Jack Jansen, {philabs|decvax}!mcvax!vu44!jack

bsa@ncoast.UUCP (The WITNESS) (09/17/84)

[gollum :-)]

> From: rch@brunix.UUCP (Rich Yampell)

> >Bennet Todd suggests that arrays of labels might be useful
> >for jump tables.  That's exactly the purpose of the
> >switch statement.
> 
> true, but what if you want to update the jump table on the fly?
> (not that I would personally want to-- it does seem a bit hacky-- but
>  this is, after all, a discussion of what "might be useful")

Might be, or perhaps "is".  I have already made use of, on my own, a "call
table" using the following struct:

	struct cmdtab {
		char *c_name[10];
		int (*c_fn)();
	};

This is used in a program where a number of options exist, depending on the
first character of the command string: '!' shells it, '#' execs it, and '*'
does a lookup in the cmdtab list.  I could see uses for a "label table" in
this, for special-purpose operations (such as an exit statement; currently,
you have to prefefine an exit character, making it difficult to build tables
on the fly, but a label option would fix this while providing for other
contingencies as well).  I haven't tried it, though; it probably won't work
on someone's machine, and I am trying to be halfway portable.  (And failed
already; the tables built on the fly are directory menus, and won't work under
4.2. :-)  (I LOVE compatibility :-)

--bsa

bright@dataio.UUCP (Emperor) (09/18/84)

I have looked at a number of C compilers (approx. 10), and all of them
generated jump tables for switch statements under the right conditions.
These conditions are generally:
	(max case value - min case value)
	--------------------------------- < (some small constant)
	(total number of cases)

	and (total number of cases) < (another small constant)

When this relation was not true, one of the following algorithms
was generated:
	a sequence of compare-branches
	a table of values and corresponding addresses was searched
	a hard-coded binary tree search
The compilers I looked at included various unix compilers and microprocessor
compilers.

arnold@gatech.UUCP (Mister Snufilupagus) (09/19/84)

> 	In response to the idea of switches implementing jump tables, I would
> 	like to know how many C compilers really generate jump tables.

The Georgia Tech C compiler for Prime computers implements switches as
a CGT instruction.  Guess what this is.  Yes, believe it or not, a Computed
GOTO instruction, in the hardware! (yuch, barf...)

It is exactly a jump table, implemented in the micro code.  Very fast.  You
put the value in the A register.  The next word contains the number of one
word addresses following the CGT, and the data itself.  The A register
is used as the index into the list of addresses following the instruction:

	LDA  <something>
	CGT
	DATA	<number of addresses + 1>
	ADDR1
	ADDR2
	ADDR3
	....

So at least one compile does use jump tables.  The Cyber Pascal compiler
will also generate a jump table in certain conditions, which are fairly
common, especially in student code.
-- 
Arnold Robbins
CSNET: arnold@gatech	ARPA:	arnold%gatech.csnet@csnet-relay.arpa
UUCP: { akgua, allegra, hplabs, ihnp4 }!gatech!arnold

Can you tell me how to get, how to get to Sesame Street?

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (09/19/84)

I don't see that switch implementation is a C language definition issue.
The C compilers I use the most all generate different code for different
types of switches, generally in an attempt to optimize execution speed.

Having the user tell the compiler how to do this is terrible.  It is easy
to use switch for reasonably-sized "jump" tables and let the existing
switch optimization go to work.

matt@ucla-cs.UUCP (09/24/84)

#endif BUG

>>Bennet Todd suggests that arrays of labels might be useful
>>for jump tables.  That's exactly the purpose of the
>>switch statement.

>true, but what if you want to update the jump table on the fly?
>(not that I would personally want to-- it does seem a bit hacky-- but
> this is, after all, a discussion of what "might be useful")

How about using an extra level of indirection in the switch statement?
Instead of:

	switch(i) { ... }

use:

	switch (jump[i]) { ... }

The `jump' array can be updated on the fly, of course.  The possible 
values of `i' should be packed as tightly as possible for effective 
memory utilization in the `jump' array.

The extra execution cost for this method is likely to be neglible in 
all but the most demanding applications.

Now can we get rid of &LABEL?
						- Matt
-------
UUCP:	{ucbvax,ihnp4}!ucla-cs!locus.matt
ARPA:	matt@ucla-locus

manis@ubc-vision.CDN (Vincent Manis) (09/25/84)

The decision as to whether to use jump tables
rather than a linear scan of a value/address table
is certainly a fairly trivial thing for any compiler
to do, and one should most certainly not expect programmers
to have to think about it. The BCPL/370 compiler written at
Cambridge about 1970 did that properly, and I can see no
reason why any C compiler would find it hard to do.

Essentially, you measure the "packing factor" of an indexed jump 
table, and if it is lower than some figure (say 50%, but it
would depend on how precious address space and CPU cycles are),
you select the linear scan, and if the packing factor is greater 
than 50% you use the indexed jump.

The packing factor is computed by determining the range
(max case value-min case value) and dividing by the number
of entries.

I personally can see absolutely no use whatsoever for &label, 
(&function, on the other hand is extremely useful), and would
be quite happy to see its existence deferred indefinitely.

Tli@usc-eclb.ARPA (10/03/84)

From:  Tony Li <Tli@usc-eclb.ARPA>

    Date: Wednesday, 19 September 1984  09:23-PDT
    From: decvax!mcnc!akgua!gatech!arnold at UCB-VAX.ARPA
    To:   Info-C at BRL-TGR.ARPA
    Re:   Using &LABEL

    > 	In response to the idea of switches implementing jump tables, I would
    > 	like to know how many C compilers really generate jump tables.

The Vax/VMS C compiler also generates jump tables.  This means that
you have to be REALLY carefull about using "switch".  Sigh.

Cheers, 
Tony ;-)