goto instruction

Programming, for all ages and all languages.
sancho1980
Member
Member
Posts: 199
Joined: Fri Jul 13, 2007 6:37 am
Location: Stuttgart/Germany
Contact:

goto instruction

Post by sancho1980 »

In our company I kind of had an argument with our senior programmer about the use of the goto instruction.
I know it's considered to be harmful, but we have already a convention in our company to use gotos to jump to the end of a function for cleanup purposes. While talking about that with him, I said I could also think of other situations where gotos can be helpful and he asked which and I said I oftentimes like to use them to jump over code, so instead of writing something like:

Code: Select all

int func()
{
    step1;
    step2;
    step3;
    if (x) {
        step4;
        step5;
        step6;
        step7;
    }
    step8;
    step9;
    step10;
return 0;
}
I prefer to write

Code: Select all

int func()
{
    step1;
    step2;
    step3;
    if (!x) {
        goto over_steps4567;
    }
    step4;
    step5;
    step6;
    step7;
over_steps4567:
    step8;
    step9;
    step10;
return 0;
}
What I like about this is above all that it avoids indentation, and I don't think it's bad because it's only a forward goto and now jumping around blindly from a to z to b.

He told me he didn't agree at all and asked me whether I thought I was smarter than all these programmers out there who say goto is bad and said I wasn't allowed to write such kind of code any more. I usually don't bother too much when he criticises that I place too many or too few blank lines between my functions or whatever detail of my coding style he doesn't like, but this really brought me upset. What do you guys think; is this already "bad use" of goto?
a5498828
Member
Member
Posts: 99
Joined: Thu Aug 12, 2010 7:25 am

Re: goto instruction

Post by a5498828 »

c is not an asm, you have functions. first code is much better.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: goto instruction

Post by gerryg400 »

I'm afraid I agree with him. It would not pass code review here. Not, in the first instance because you used goto, but because you avoided indentation. Indentation in this case should be used to show at a cursory glance that the middle block of code is not part of the 'always-executed' code path. This would be more likely to be passed

Code: Select all

int func()
{
    step1;
    step2;
    step3;
    if (!x) {
        goto over_steps4567;
    }
    else {
        step4;
        step5;
        step6;
        step7;
    }
over_steps4567:
    step8;
    step9;
    step10;
return 0;
}
At this point the goto is unnecessary, as it usually is in properly structured c, and eventually the code is written as he originally suggested.
If a trainstation is where trains stop, what is a workstation ?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: goto instruction

Post by neon »

Hello,

If a function constitutes of that many steps that require the use of goto to improve readability I would look into ways to simplify the function by breaking it apart.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: goto instruction

Post by linguofreak »

sancho1980 wrote:What I like about this is above all that it avoids indentation, and I don't think it's bad because it's only a forward goto and now jumping around blindly from a to z to b.
Indentation is good for readability. Furthermore, if you absolutely want to avoid indentation, you can do this:

Code: Select all

int func()
{
    step1;
    step2;
    step3;
    if (x) {
    step4;
    step5;
    step6;
    step7;
    }
    step8;
    step9;
    step10;
return 0;
}
or even

Code: Select all

int func(){step1;step2;step3;if (x){step4;step5;step6;step7;}step8;step9;step10;return 0;}
Either bit of code is just as valid as far as the compiler is concerned. I wouldn't expect your boss to be very happy with it though, as most people find either one much less readable. The way he wants you to write it makes it easier for other people to work with.
What do you guys think; is this already "bad use" of goto?
Yes.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: goto instruction

Post by bewing »

I disagree with just about everyone here. Using 'goto' is not a question of intelligence, or badness. It is merely a religious/philosophical question. A bit more than a question of mere style, but still.

The CPU uses goto/JMP for just about every line of code you write. Avoiding 'goto' is an attempt to avoid what the CPU does best, and that is one of the reasons why everyone's code today runs so slowly, and is such immense fatware.

Creating functions as a series of 'steps' can be much more readable than trying to create code blocks with indentation. To blindly do one or the other is foolish.

Unfortunately, the programming world is just as full of religious zealots as the Southern USA.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: goto instruction

Post by linguofreak »

bewing wrote:I disagree with just about everyone here. Using 'goto' is not a question of intelligence, or badness. It is merely a religious/philosophical question. A bit more than a question of mere style, but still.

The CPU uses goto/JMP for just about every line of code you write. Avoiding 'goto' is an attempt to avoid what the CPU does best, and that is one of the reasons why everyone's code today runs so slowly, and is such immense fatware.
Goto *is* often avoided a bit too religiously, but in the OP's case I'm pretty sure it will run slower, since, when it's finally turned into machine code, you'll have 2 JMP's where you only need one. The if statement already has an implicit JMP if x is false, and then the goto is a JMP, and so you end up doing a JMP/Goto regardless of the value of x, whereas you only *need* a JMP if x is false, and if x is true you can just let execution continue linearly.
Creating functions as a series of 'steps' can be much more readable than trying to create code blocks with indentation. To blindly do one or the other is foolish.
The "steps" issue, the goto issue, and the indentation issue here are three separate issues. For the purposes of the OP's question, whether we do:

Code: Select all

int func()
{
    step1;
    step2;
    step3;
    if (!x) {
        goto over_steps4567;
    }
    step4;
    step5;
    step6;
    step7;
over_steps4567:
    step8;
    step9;
    step10;
return 0;
}
or

Code: Select all

int func()
{
    step1;
    if (!x) {
        goto over_step2;
    }
    step2;
over_steps2:
    step3;
return 0;
}
is moot. As is whether we do:

Code: Select all

int func()
{
    step1;
    if (!x) {
        goto over_step2;
    }
    step2;
over_steps2:
    step3;
return 0;
}
or

Code: Select all

int func(){ step1; if (!x) { goto over_step2; } step2; over_steps2: step3; return 0;}
There are reasons why one would (or would not) want to do each one, but it's orthogonal to the goto issue.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: goto instruction

Post by gerryg400 »

bewing wrote:I disagree with just about everyone here. Using 'goto' is not a question of intelligence, or badness. It is merely a religious/philosophical question. A bit more than a question of mere style, but still.

The CPU uses goto/JMP for just about every line of code you write. Avoiding 'goto' is an attempt to avoid what the CPU does best, and that is one of the reasons why everyone's code today runs so slowly, and is such immense fatware.

Creating functions as a series of 'steps' can be much more readable than trying to create code blocks with indentation. To blindly do one or the other is foolish.

Unfortunately, the programming world is just as full of religious zealots as the Southern USA.
Bewing, nobody said that using goto was related to intelligence or badness. In fact most of the comments centred around the need for indenting the code. And we didn't say that indenting or not indenting was always bad. Most of the comments were about this particular example. I don't believe that you disagree with just about everyone here.
If a trainstation is where trains stop, what is a workstation ?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: goto instruction

Post by Solar »

bewing wrote:The CPU uses goto/JMP for just about every line of code you write. Avoiding 'goto' is an attempt to avoid what the CPU does best...
I counter that with another quote:
Martin Fowler wrote:Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
That's why 'goto' is shunned. Anyone who can draw a Nassy-Shneiderman diagram knows what I mean.
...and that is one of the reasons why everyone's code today runs so slowly, and is such immense fatware.
You're kidding, right? I mean, do you really believe what you just said? That software today runs "so slow" because people no longer use 'goto'?

Edit: Or that the two examples given by sancho1980 would actually result in any difference in the compiled code?

#-o
Every good solution is obvious once you've found it.
Fanael
Member
Member
Posts: 38
Joined: Fri Oct 16, 2009 9:20 am

Re: goto instruction

Post by Fanael »

bewing wrote:Avoiding 'goto' is an attempt to avoid what the CPU does best
What CPU does best are simple arithmetic (addition, subtraction), bitwise operations, and the like. CPUs don't like branching, actually. Especially the ones mispredicted by the branch predictor.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: goto instruction

Post by turdus »

Actually goto can make code clearer, but your example is bad.
It's nested structures where goto come handy in structured languages, like

Code: Select all

int flag1=true;
while(flag1&&expr1){
   ....
   while(expr2){
      ....
      //and here you want to break both loops
      if(expr3) { flag1=false; break; }
   }
}
That's messy. It's much clearer to write

Code: Select all

while(expr1){
   ....
   while(expr2){
     ....
     if(expr3) goto break_loops;
   }
}
break_loops:
Only use goto if it does not lead to spaghetti-code, and you'll be fine.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: goto instruction

Post by Solar »

turdus wrote:Actually goto can make code clearer...
...but not as much as properly designed code.
...but your example is bad. [...] Only use goto if it does not lead to spaghetti-code, and you'll be fine.
Any goto by definition leads to spaghetti code. It might jump to the right place, and it might take into account any variable assignments it jumped over, but you simply never know unless there is additional documentation. Unfortunately, the attitudes "goto is not evil" and "code does not need comments" too often go hand in hand.

Code: Select all

inline void foo()
{
    while ( expr1 )
    {
        // ...
        while ( expr2 )
        {
            // ...
            if ( expr3 ) return;
        }
    }
}
Every good solution is obvious once you've found it.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: goto instruction

Post by turdus »

Solar wrote:
turdus wrote:Actually goto can make code clearer...
...but not as much as properly designed code.
Agree. In nearly 20 years of development I found only a few situations where goto was better (or even the only solution). Less than 1%.
Solar wrote: Any goto by definition leads to spaghetti code. It might jump to the right place, and it might take into account any variable assignments it jumped over, but you simply never know unless there is additional documentation. Unfortunately, the attitudes "goto is not evil" and "code does not need comments" too often go hand in hand.
Disagree on that. Imagine a code where no goto crosses, it wouldn't be a unfollowable spaghetti-code. But it's quite rare, so you are right that comment is a must.

Your code (which is good and readable solution) has a disadvantage that you introduced plus stack handling and two more branches. This could be a problem if performance matters (and frankly speaking in a kernel almost all the time it matters). So your code is good, but not universal, I do not recommend to use it without examining the concrete situation.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: goto instruction

Post by Combuster »

Ever heard of compiler optimalisations (read: inline functions)?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: goto instruction

Post by Solar »

turdus wrote:Your code (which is good and readable solution) has a disadvantage that you introduced plus stack handling...
inline...
...and two more branches.
Nope, I copied your example exactly, including the check on expr1 and expr2.
Every good solution is obvious once you've found it.
Locked