[comp.misc] Re^2: The "evil" GOTO

roemer@cs.vu.nl (Roemer Lievaart) (05/09/89)

In article <13113@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>       if (cond1) {
>          [...A...]   /* lots of code */
>          goto LABEL;}
>       else if (cond2) {
> LABEL:   [...B...]   /* lots more code */
>       }
>

Ugh. I would choke on this several times if I would have to maintain this.
And I know what I am talking about, for I sometimes use goto's if
I haven't planned everything well in advance. But only in very
simple cases (like the one described).
When reading such code over again, I *always* end up confused, even a week
after I wrote it.

BTW. Why not:

	if (cond1 || cond2) {
	    if (cond1) {
		[...A...]
	    }
	    [...B...]
	}

Simple and neat.
And understandable: B is done if cond1 or if cond2, A only if cond1.
In the goto-version this is not clear immediately (to me it isn't!)

Of course, if cond1 has side-effects or is very complicated, one should read:

	
	bool condition1;

	condition1 = cond1;
	if (condition1 || cond2) {
	    if (condition1) {
		[...A...]
	    }
	    [...B...]
	}

People may throw up at throwing in extra variables like this. I used to.
Until I discovered that if you *name* them right, they really even make
things much *easier* to read. Variable naming is very important, especially
in cases like these.

The problem with goto's is:
When you don't use them often, you have troubles reading or maintaining
code which has them.
If you do use them often, you're very probably writing spaghetti code.

	-- Roemer
____________________________________________________________________________
Roemer B. Lievaart | 	LISP :
Amsterdam, Holland | 	a Lot of Irritating, Stupid Parenthesis
roemer@cs.vu.nl    | 

jlg@lanl.gov (Jim Giles) (05/10/89)

From article <2468@solo9.cs.vu.nl>, by roemer@cs.vu.nl (Roemer Lievaart):
> In article <13113@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
>>       if (cond1) {
>>          [...A...]   /* lots of code */
>>          goto LABEL;}
>>       else if (cond2) {
>> LABEL:   [...B...]   /* lots more code */
>>       }
>>
> 
> Ugh. I would choke on this several times if I would have to maintain this.
> [...]
> BTW. Why not:
> 
> 	if (cond1 || cond2) {
> 	    if (cond1) {
> 		[...A...]
> 	    }
> 	    [...B...]
> 	}

Bletch!!  This is worse than implementing B as a procedure.  I duplicates
the evaluation of the condition.  It doesn't generalize well at all:

      if (cond1) {
         [...A...]   /* lots of code */
         goto LABEL;}
      else if (cond1_prime) {
         [...A_prime...] /* lots of code */
         goto LABEL;}

      [...]

      else if (cond1_nprime) {
         [...A_nprime...] /* lots of code */
         goto LABEL;} 
      else if (cond2) {
LABEL:   [...B...]   /* lots more code */
      }

By your method, the duplicated condition evaluation would be _very_
long and difficult to read.

luuk@cs.vu.nl (Luuk Uljee) (05/11/89)

geoff@cs.warwick.ac.uk (Geoff Rimmer) writes:


>Here is my solution.  Which does the same as that of the original
>poster, and in addition:

>(a) it checks the buffer overflowing;
>(b) it checks for EOF
>(c) it is correct C code

>-----------------------------------------------------------------------------
>#include <stdio.h>

>main()
>{
>	char str[4];
>	printf("Enter your sex: ");
>	do
>	{
>		fflush(stdin);
>		if (!fgets(str,3,stdin)) exit(1);
>	} while (*str!="m" && *str!="f") ? printf("m or f only: "):0);
>	printf("sex is %c\n",*str);
>}
>-----------------------------------------------------------------------------

Hey, you probably never done any programming in LISP! Otherwise you
would have known of an option 'showmatch' in vi :-) (BEEP) ...

Besides that, this code contains still all off the unstructered
ugliness - jumping out of a loop (exit)
	 - no comments (no comment)
	 - inconsistent use of return value (printf) 
	 - comparison of unequal types (sometimes there is really no need
						for comments)
	 - Use of unexplained arbitrary constants (4)
	 - etc etc ...


|cc% cc -c c.c                               | Luuk Uljee
|"c.c", line 1989: invalid identifier "goto" | email: luuk@cs.vu.nl
| "How bright the future could be ..... "    | (I knew it was a joke Geoff ... )

jws@hpcljws.HP.COM (John Stafford) (05/12/89)

Beware that fflush(stdin), to the best of my knowledge, is not defined
to be meaningful by any standard I've seen.  It may work some places,
but it won't work everywhere.

d.jba@harald.ruc.dk (Jan B. Andersen) (05/12/89)

jacka@hpcupt1.HP.COM (Jack C. Armstrong) writes:

>In all of this GOTO/NOGOTO nonsense, no one seems to have mentioned just
>WHY gotos are so ugly - it's not the goto statement that causes readability
>problems - is the %&#!$! label!  When reading source written by others (or
>myself, more than 5 minutes ago) the presense of a label tells me *somebody*,
>*somewhere* does a goto to this location.  The question is - who? from where?

This brings back memories of a paper I saw several years ago describing
a new language construct, the COMEFROM statement along with several
other humourous ideas ( :-D ) !
-- 
Jan B. Andersen, Datalogi 19.1     .---------------------------.       /^^^\
Roskilde Universitetscenter       ( "SIMULA does it with CLASS" )     { o_o }
Postbox 260,                       `---------------------------'  <--- \ o /
DK-4000  Roskilde (Denmark)       IfUmust: +45 46 75 77 11            -mm--mm-