Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site duke.UUCP Path: utzoo!watmath!clyde!bonnie!akgua!mcnc!duke!crm From: crm@duke.UUCP (Charlie Martin) Newsgroups: net.lang.c Subject: Re: Re: Breaking out of several nested loops (& ANSI C) Message-ID: <4901@duke.UUCP> Date: Fri, 12-Oct-84 13:58:16 EDT Article-I.D.: duke.4901 Posted: Fri Oct 12 13:58:16 1984 Date-Received: Sun, 14-Oct-84 05:58:12 EDT References: <129@ssc-vax.UUCP>, <1801@pegasus.UUCP> <4886@duke.UUCP>, <2085@rochester.UUCP> Organization: Duke University Lines: 74 The problem with getting into a religious discussion is that everyone seems to think that you have a religious opinion... Let me make another attempt to make my argument clear -- I claim that while it is indeed true that ANY algorithm can be expressed in proper structured-programming-without-goto's (proven by Boehm & Jacopini), there are things which one often wants to do which are best expressed in current programming languages (modulo efficiency constraints) by doing them with a goto. The example that we have been discussing is one of those. The solutions that are available are: use a branching statement to bust out of the loop; have a language construct which magically hides a branching contruct busting out of the loop; or put a new boolean test into each outer loop, so that processing terminates when that is set. The third solution is the one that can be inferred from the original proof. It has some advantages for proof-of-correctness. The second method is the one that is used by the break (and continue) statements, and is the one that I feel is correct. It limits the scope of the goto, and doesn't tempt people into indiscetions as often. However, these statements as they exist won't cover certain cases: for example, a simple break won't take you out of nested loops; a more difficult example is something like this: /* code for user input */ while ( not complete ) do retry: /* transfer to this point for retry of whole thing */ while( not right) do get input a, b, c if ABORT-INPUT received goto retry fi od od /* end example */. In both of these cases, WHILE IT IS PROVABLY POSSIBLE TO WRITE A GOTO-LESS PROGRAM TO DO THEM, the solution with goto's has advantages in speed and amount of generated code-and-data. The best solution is something that eliminates goto's or limits their ability to muck up control flow, but that provides for all those odd situations which these exemplify. A label-continue/label-break sentax might do that effectively (say by defining the label as an optional part of the beginning and/or ending of a loop) but I want to feel convinced that it is going to be able to do everything I would use a goto for (which isn't damnall much, I admit -- I've only written one goto in C ever.) (And wouldn't have ever written one in Pascal at all, were it not for the absense of a loop break.) My only complaints about the labelled-loop/break-label solution are these: 1) it's a goto anyway -- why fuss about it? In particular, why claim it is more ``structured'' than the same control- flow with the horrible word ``goto'' in the code? 2) The notation suggested is itself counter-intuitive -- you are G*T*-ing to a label, but the label is up at the top and you are going to the bottom (!?) 3) do these solutions *really* cover everything? Are you going to leave setjmp/longjmp in the language? They can be transformed out too, you know... Charlie Martin (...mcnc!duke!crm)