ginaspider ([info]ginaspider) wrote,
@ 2008-12-02 16:58:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Dirty words in computer language
GOTO

How does everyone feel about goto in C? I find some people have strong feelings against goto, I don't understand. I don't use it extensively but I do find that the occasional goto is useful and generally easy to follow. As long as something is in the language I feel it's fair game. Do you think goto will be depreciated?



(Post a new comment)


[info]approachmdnight
2008-12-03 05:17 am UTC (link)
I think it should only be used in situations where it makes more sense than the available loop/control flow keywords. I've seen it occasionally in systems code to jump from within a nested loop to an error handler, for example.

I don't think it will be deprecated -- it's used heavily in the Linux kernel. ;)

(Reply to this)


[info]sigil
2008-12-03 05:30 am UTC (link)
I can't imagine them deprecating the goto command. I think the general dislike of the command is from inexperienced coders using it excessively and creating what we used to call 'spaghetti code' that was impossible to follow.

(Reply to this) (Thread)


[info]ginaspider
2008-12-03 05:57 am UTC (link)
Personally I have never seen this "spaghetti code" from gotos in C that everyone talks about. Have you?

I feel this comes from it being a lot easier not to use gotos most of the time, i argue, even to the programmer armed with very little experience with C.

(Reply to this) (Parent)(Thread)


[info]tcinseattle
2008-12-03 06:35 am UTC (link)
Yes.
horrible, monstrous, evil tangled nonsensical code. Several pages of numbered labels with weird chunks of code in between them.
Firmware, translated into C from the original PIC assembler by an old EE who didn't ever learn C - and so didn't limit himself to our controlled and regimented concepts of _functions_ or the (for him) very limiting for/while dichotomy. We were explicitly instructed not to touch it.

Throwing an exception is basically a GOTO, with a nice stack-climbing add-on. I think it's fair to use a goto to jump out of the middle of a bunch of nested loops, however;
not before you've typed 'for' and 'while' at least 5000 times. Each.
and not without facing a firing squad of your peers (code review).

(Reply to this) (Parent)(Thread)


[info]ginaspider
2008-12-03 06:48 am UTC (link)
Hmm.. translated code. Adventure comes to mind as translated-to-c code that looks pretty bad. I'm not sure if this really counts though.

Yeah! good example, an exception. I brought up this topic because I've just written a flood-fill routine that cleans up and leaves if the painter's pixel reaches outside of a clipping square. It's just a lot easier to do then repeat code over and over within the routine- It's an exception. I always feel guilt though, tcinseattle, whenever I use a goto. It's like using dirty words around my mother, you know what I mean? Sometimes Goto gets straight to the point though.

(Reply to this) (Parent)(Thread)


[info]sigil
2008-12-03 03:32 pm UTC (link)
I haven't seen 'spaghetti code' in C, but back in the day I have seen it in FORTRAN and PASCAL and I've heard stories about COBOL code that no human being could ever understand. Back when I was learning BASIC, I wrote a lot of what would now be called 'spaghetti code' but I have the excuse of being 14 at the time and trying to write ZORK in BASIC.

(Reply to this) (Parent)


[info]ginaspider
2008-12-03 03:35 pm UTC (link)
for your entertainment here's a snippet of adventure. It's translated from Fortran, mind you.

		case 1:			/* take = 8010		*/
			if (atloc[loc] == 0 || linkx[atloc[loc]] != 0)
				goto l8000;
			for (i = 1; i <= 5; i++)
				if (dloc[i] == loc && dflag >= 2)
					goto l8000;
			obj = atloc[loc];
			goto l9010;
		case 2: case 3: case 9:		/* 8000 : drop, say, wave */
		case 10: case 16: case 17:	/* calm, rub, toss	*/
		case 19: case 21: case 28:	/* find, feed, break	*/
		case 29:			/* wake			*/
l8000:			printf("%s what?\n", wd1);
			obj = 0;
			goto l2600;
		case 4: case 6:		/* 8040 open, lock	*/
			spk = 28;
			if (here(clam))
				obj = clam;
			if (here(oyster))
				obj = oyster;
			if (at(door))
				obj = door;
			if (at(grate))
				obj = grate;
			if (obj != 0 && here(chain))
				goto l8000;
			if (here(chain))
				obj = chain;
			if (obj == 0)
				goto l2011;
			goto l9040;
		case 5: goto l2009;		/* nothing		*/
		case 7: goto l9070;		/* on			*/
		case 8: goto l9080;		/* off			*/
		case 11: goto l8000;	/* walk			*/
		case 12: goto l9120;	/* kill			*/
		case 13: goto l9130;	/* pour			*/
		case 14:			/* eat: 8140		*/
			if (!here(food))
				goto l8000;
l8142:			dstroy(food);
			spk = 72;
			goto l2011;
		case 15: goto l9150;	/* drink		*/
		case 18:			/* quit: 8180		*/
			gaveup = yes(22, 54, 54);
			if (gaveup)
				done(2);	/* 8185			*/
			goto l2012;
		case 20:			/* invent = 8200	*/
			spk = 98;
			for (i = 1; i <= 100; i++) {
				if (i != bear && toting(i)) {
					if (spk == 98)
						rspeak(99);
					blklin = FALSE;
					pspeak(i, -1);
					blklin = TRUE;
					spk = 0;
				}
			}
			if (toting(bear))
				spk = 141;
			goto l2011;
		case 22: goto l9220;	/* fill			*/
		case 23: goto l9230;	/* blast		*/
		case 24:			/* score: 8240		*/
			scorng = TRUE;
			printf("If you were to quit now, you would score");
			printf(" %d out of a possible ", score());
			printf("%d.", mxscor);
			scorng = FALSE;
			gaveup = yes(143, 54, 54);
			if (gaveup)
				done(2);
			goto l2012;
		case 25:			/* foo: 8250		*/
			k = vocab(wd1, 3, 0);
			spk = 42;
			if (foobar == 1 - k)
				goto l8252;
			if (foobar != 0)
				spk = 151;
			goto l2011;

(Reply to this) (Parent)(Thread)


[info]sigil
2008-12-03 03:41 pm UTC (link)
Yup. That's spaghetti code!

(Reply to this) (Parent)


[info]uniheliodem
2008-12-03 06:08 pm UTC (link)
In the words of Hank Hill, “BWAH!”

I was thinking of outlining the number of style errors I could find in that snippet, but I think I would be stating the obvious.

I'm going to hide under my desk now until my brain stops hurting. ;-)

(Reply to this) (Parent)


[info]teraflops
2008-12-03 06:16 am UTC (link)
I think it's generally a cheat, and that if you're using one it's a sign that your code is structurally unsound, and should probably be reworked. That said, sometimes the cost/benefit ratio nudges you toward a quick fix, and in that case it's understandable that you might use one.

(Reply to this) (Thread)


[info]ginaspider
2008-12-03 06:25 am UTC (link)
Structurally unsound, what do you mean by that?

(Reply to this) (Parent)(Thread)


[info]tcinseattle
2008-12-03 07:37 am UTC (link)
brittle / inflexible - unresistant to alteration.

(Reply to this) (Parent)


[info]uniheliodem
2008-12-03 01:56 pm UTC (link)
I think there has only been one case in my professional career when I've seen a goto in human written code and thought, “Yeah, that's okay.”

I doubt that goto will ever be removed from the language, it would break things that do require it. I've written a few source-source compilers that required a goto here and there. I know that in systems programming (e.g. kernels and device drivers) one is often hit by constraints that require a goto (for instance, when switching between stacks or when specifically trying not to play with the stack). In fact, this is where I found my one acceptable goto.

Ninety-nine times out of one hundred, when I've seen goto, the code just needs to be refactored. When working with a higher level language (which I consider C/C++), priorities are a bit different. The first priority is to make the code correct and legible. The second priority is to make it fast. When the second priority breaks the first priority, I expect to see plenty of documentation. I consider higher level languages to be about clearly capturing algorithms in a human understandable manner. Otherwise, just write it all in assembler.

Unfortunately, the industry is full of people who believe that only they will read their own code. These are the sorts of people who frequently use language features without considering the implications to future maintainability. It takes a long time for a developer to get past the concept of writing complex and “smart” code and discover the zen of writing clear, concise, and elegant code. Nine times out of ten, the latter out-performs the former anyway.

(Reply to this) (Thread)


[info]ginaspider
2008-12-03 03:37 pm UTC (link)
"It takes a long time for a developer to get past the concept of writing complex and “smart” code and discover the zen of writing clear, concise, and elegant code"

Hmm.. interesting comment

(Reply to this) (Parent)


[info]sigil
2008-12-03 03:39 pm UTC (link)
I think you've hit it on the head with legible vs. fast. Back when CPU cycles and memory were at a premium, coding was much more an exercise in writing something that would execute in a timely fashion with as little footprint in RAM as possible - a lot of times it was much more efficient to just goto than follow a more structured loop or control flow. Of course, this was why a lot of code required massive documentation.

For me, the big wake up call on elegant vs. "smart" code was coming back to something I'd written years later and having to figure out exactly what I did and why I'd done it. Nothing like trying to decipher and diagnose your own undocumented code to open your eyes.

(Reply to this) (Parent)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…