[linux-elitists] Goto vs. named scopes

Jim Bray jb@as220.org
Sat Jan 11 09:29:09 PST 2003

> What I find over the years is that like most everything else, goto is abused. 
> There are certain cases where a goto works best, and it's hard to dispute 
> that. As an example, (W.) Richard Stevens used goto statements in some of his 
> socket routines, and I would challenge someone to come up with a better 
> solution to the problem at hand in less machine cycles. It just can't be done.

  Back in the early 1980s I came up with ideas for dealing with this.

Allow all scopes to be named, and allow break and continue to operate
with those names. Add to those a 'restart' operation and you're pretty
much all set.

outer: {
	get_lock: for (...) {
		if (interrupted)
			restart get_lock;
		if (error)
			break outer;
	more code;

 The original posting:


Here are some ideas I have had lying around in a file. I sent them out
ARPA unix-wizards when there was talk of a C discussion starting up, but it
never happened. The only responses I got were from a couple of people who
seemed to be coming from a Pascal viewpoint and pointed out these ideas
were really just disguised gotos and would interfere with "provability".
Well, it seems to me that all loops are just disguised gotos and etc., put
together in certain predefined ways that make them more pleasant to deal
with. As for provability: someone who is really concerned with formal
verification had probably best find some Pascal-derived language to work
with. Me, I would rather be condemned to driving a tourist bus for the rest
of my life.

Anyways: there was one kind soul who suggested that I take a look at
net.lang.c. As it happened, we were that very week in the process of coming up
on USENET, so it was an apt suggestion indeed.


     Needs  a  "restart"  construct  to  reenter a for loop (as for example when
    having slept in it and needing to completely recommence);

-- This is a problem that comes up in the kernel when one is examining a
changeable data-structure, does a sleep, and then wants to resume the traversal
from the beginning because things might have changed while one was asleep.
Generally this traversal constitutes both a logical and a physical scope.
It is a logical scope in that it is a local body of action which can often
have private variables --counters or element pointers, for example; it usually
takes place within a physical scope: a loop of some sort, or perhaps a plain
scope --a set of brackets to allow a scope-local variable declaration, which
is a trick I am very fond of to do my own register allocation in the absence
of compiler assistance, and which I notice is being used with increasing
frequency by the USG people (quite a bit in sys5, in fact). Note that this
scoping and localization of variables actually improves readability and
provability if done properly, altho' my main purpose code quality.
  In any case: "restart <scope_name>" is generally accomplished either by
putting the actual work-performing loop in an otherwise spurious for-loop
which is somehow continued, or more commonly by simply giving up and having
a label "loop:" at the beginning of the whole thing and then transferring
control to it from within the traversal scope. The idea of "restart" has
exactly the same effect, and would generate the same code. The same cannot
be said for the Pascal solution of redundant tests and silly little boolean
flags and other symptoms of terminal constipation brought on by mortal fear
of gotos, anything that looks or acts like them, or anything else that might
actually serve any useful purpose.

REAL PROGRAMMERS DO NOT EAT QUICHE (when anybody is looking who might tell)

More on this and other stories later. To continue (ahem):

    Loops  of  all  kinds,  and  perhaps all scopes, should be nameable. Break,
  continue, and the proposed restart could accept these labels as  an  optional
  argument: when used in this way, it would indicate that the desired action be
  performed on the given scope, with the  default  being  as  for  the  current

OK, so sure, you could write code that would stagger around like a drunken flea
on a St. Bernard for a while and then either get squashed or go for your
kernel's jugular. But you can do that already, even without gotos. There is no
point in trying to protect programmers from themselves. It can't be done.
But these ideas, contrary to their detractors' objections, would in my opinion
improve both verifiability and much more importantly readability over both
the current thread of gotos which real programmers use and the grotesque and
anti-optimal mess of redundant tests and little flags which seems to be the
Pascal way of doing these thing and which even a really slick optimizer
couldn't do much with. It is probably not possible to do without gotos
altogether and still have the generated code be precisely what one intends
it to be, but these ideas would obviate them in a great many of the instances
in which they are now used, while replacing them with constructs which would
enhance readability, verifiability and optimality of resource allocation.

--Jim Bray
		Arpa: jbray@bbn-unix
		UUCP: decvax!genrad!wjh12!bbncca!jbray

More information about the linux-elitists mailing list