Quick question about goto in C++

Started by
33 comments, last by starmole 18 years, 8 months ago
Quote:Original post by Anonymous Poster
When a goto comes up the computer has to look through the code to find where you are looking for, which takes up a bit more time than a loop would.


No. This is resolved at compile time. Furthermore, internally, a for-loop really is just a increment/test/goto package deal. You can have cache misses with a for-loop just as well as with a goto.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Advertisement
Quote:Original post by Fruny
They are also extremely useful is machine-generated code. In particular, parser generators (like bison) which translate the grammar into a state machine, and the state machine into actual C code - riddled with gotos.


The only limitation on goto being that of being hard to parse and manipulate (but not create) by humans, using it in machine-generated code is an all-win situation.

Quote:
Assignment: What were the popular languages when Dijkstra's paper was written? Reframe the goto question in the context of those languages. Compare and contrast with current programming techniques, paradigms and languages. You have 180 minutes. [wink]


PDP-10 assembler and LISP? What do you mean, wrong century?
Quote:Original post by polly
From the classic article: Go To Statement Considered Harmful.

Goto Considered Harmful Considered Harmful
More formally :

Languages like C/C++ and Java are known as structured languages - they are based around structured blocks of code for/while loops if statements etc where the points of entry and exit are defined at the top/bottom of the block. The thing with gotos (and breaks and continues in loops) is that you can break the structuredness of your code by jumping out in the middle of a block of code.

As the a previous post said :

The main problems with unstructured code are that it makes code harder to read and harder to refactor.

Gotos are particularly dangerous because you can basically jump anywhere in a program in an unstructured way which makes bugs more likely (and harder to detect)

There are certain uses of gotos (depending on who you speak to) which are acceptable - for example to simulate exceptions (like in C++) or On Error in VB in languages that don't support such a concept directly (like in C). But you have to pay a lot of attention to how you do it
Which is more readable:
void DoSomething(Object* ParentObject){  int WithSomething = 5;  do  {    Action* MyAction = DoStuff(WithSomething);    ParentObject->DoAction(MyAction);    MyAction->Update();    if(ParentObject->SomethingHappens())    {      WithSomething = 10;      continue;    }  } while(0);}

or
void DoSomething(Object* ParentObject){  int WithSomething = 5;MyLabel:  Action* MyAction = DoStuff(WithSomething);  ParentObject->DoAction(MyAction);  MyAction->Update();  if(ParentObject->SomethingHappens())  {    WithSomething = 10;    goto MyLabel;  }}


You're free to disagree with me, but the first version seems more obfuscated and hackish than clear and correct.
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
The first one isn't the same as the second one.
Yes it is, it's a while(0), not a while(1), it caught me too for a bit.

It should be rewritten using a flag for the termination condition, assigned with SomethingHappens()'s return value.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
If I use a boolean, then it really will be doing something different between the two, though.
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
I may be wrong, but this looks suspiciously like a loop-with-exit[1]. Cleaner would be:

void DoSomething(Object* ParentObject){  int WithSomething = 5;  for (;;) // Or some kind of FOREVER macro  {    Action* MyAction = DoStuff(WithSomething);    ParentObject->DoAction(MyAction);    MyAction->Update();    if(!ParentObject->SomethingHappens())        break;    WithSomething = 10;  }}


[1] See Code Complete
In that particular case I would've used while(1) { ... if ... else break;} which would doubtless compile to identical or near-identical code, but I think is clearer. I'd say gotos can be useful but I don't see any good reason they should be used for constructing loops.

Edit: Ah, beaten to it.

This topic is closed to new replies.

Advertisement