Thread: Is GOTO a bad idea ever?

  1. #16
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by TheBigH View Post
    the function call and return are just gotos with different names.
    first of all, a function call is not a goto. not behind the scenes or under the hood or any other idiom you want to use to describe it. every processor I've ever come into contact with has call/return semantics in its machine language. these features are always used when available.

    if/else, for, while, do/while are all syntactic sugar over top of goto. why do we use them instead of goto? because they're the right tool for the job. there are definitely cases where goto is the right solution. but I don't believe that breaking from a nested loop is one of them.

    I don't even know why we still have threads on this subject. I'm certain that over the 40 years or so that the C language has been around, every opinion that can be offered on the subject has been heard, and either accepted as truth or rejected as folly.

    EDIT:
    in C, it's not an issue, but in C++, using goto can seriously alter program behavior, because you can jump over the initialization of a user-defined-type object, and then go on to use it as if it were initialized properly. most compilers will warn about this when you try it, but it can cause very strange behavior at times, up to, and including crashes. the behavior of a program under those conditions is undefined, and as with all undefined behavior, it is best to avoid it at all costs.
    Last edited by Elkvis; 06-13-2012 at 10:42 PM.

  2. #17
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Here is how it really is:

    New programmers should absolutely avoid `goto' not because it is inherent evil but because new programmers suck at writing code that exhibits clear intent and `goto' does a lot to make that situation worse.

    Experienced programmers know enough to make an informed decision between using `goto' if it improves the intent of the code instead of some other option that clouds the intent.

    It is simply easier to say "GOTO IS [TEH EVIL!" than explain every conceivable case where a `goto' clarifies rather than clouds intent.

    Soma

  3. #18
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    I call shenanigans.
    If for( ; ; ) doesn't work on something then than thing is not a C compiler by any stretch of the imagination.

    "goto"? Pffft, stop reminding me that it even exists. I have no use for such garbage!
    You just use a goto in code for a job interview and watch how fast they hire you ... not!
    Last edited by iMalc; 06-14-2012 at 02:57 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #19
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by oogabooga View Post
    You would have to be truly retarded not to see that goto is better in this case:
    Code:
    // with goto
    while (whatever) {
        while (something) {
            if (such_and_such)
                goto break_outer_while;
            actual_work();
        }
    }
    break_outer_while:
    
    // with idiotic flag
    while (whatever && !idiotic_flag) {
        while (something && !idiotic_flag) {
            if (such_and_such)
                idiotic_flag = 1;
            else {
                actual_work();
            }
        }
    }
    Well I guess even go-to can't fix idiotic code. The fact that the code is written in an idiotic way is no endorsement for using go to.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  5. #20
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Goto is rarely, if ever the correct solution. Even oogabooga's code doesn't warrant goto:

    Code:
    void its_own_function() {
        while (whatever) {
            while (something) {
                if (such_and_such)
                    return;
                actual_work();
            }
        }
    }
    or
    Code:
    while (whatever && something && !such_and_such) {
            actual_work();
    }
    are acceptable and non-goto solutions. In the case of bigger loops that cannot be simply combined like this, they should usually be split into separate functions.

    ----

    For example, if I had a function to go through an array of IPs, connect to them, and send 5 packets each:
    Code:
    for (i = 0; i < length; i++) {
        if (!connect())
            goto out;
        for (j = 0; j < 5; j++) 
            if (!send())
                goto out;
    }
    out:
    you could split it:
    Code:
    int send5(){
        for (j = 0; j < 5; j++)
            if (!send())
                return -1;
    }
    
    int connecttoips() {
        for (i = 0; i < length; i++) {
            if (!connect())
                break;
            if (send5() < 0)
                break;
        }
    }
    although in this case, it really isn't necessary.

  6. #21
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    There are some special cases where goto is a measurably better choice (usually against some performance metrics) than all alternatives. However the majority of programmers will never encounter those cases in practice.

    Dijkstra's article "Goto Statement considered harmful" (which someone referred to in an earlier post) provided some cases, although it is usually cited incorrectly by people (who have presumably only read the title) as providing THE case for not using goto (it actually provided a case against excessive use of goto). Donald Knuth's paper "Structured programming with go to statements" also discussed some cases. However, those papers are not for the faint hearted.

    One consequence of the Böhm-Jacopini theorem is that any program which uses goto can be rewritten without it.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #22
    Registered User
    Join Date
    May 2012
    Location
    Brasília, Brazil
    Posts
    10

    to goto or not to goto?

    Quote Originally Posted by laserlight View Post
    I repeat oogabooga's challenge: name such a compiler. A few years ago, I picked up an old book on C optimisation that recommended using such a for loop over a while (1) because compilers, old when the book was written, tended to optimise the former to that structure whereas they might actually create a loop that tested the loop condition for the latter. There was certainly no caveat that a compiler might choke on this.

    My guess is that if a compiler that does not recognise such a for loop exists today, it would be very specialised for say, embedded programming, hence rendering the notion of a cross-platform approach irrelevant to begin with.
    All right, couldn't find a compiler that does not recognize the for keyword with empty parameters.

    The while(1) statement issues a warning at my Freescale's Codewarrior 5.0 compiler: that's why I do not use it. In some cases, it issues only a notice.

    Yet, the code need to be cross-platform: these routines built for Freescale devices, for example, are compiled for MinGW's Intel i386 too. That's only one example. Only my drivers are not cross-platform.

    I heard the goto keyword optimizes the use of the stack on recursive functions. Does someone have an example?

  8. #23
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    I tend to use it when I'm in a block that allocates and deallocates a number of resources (memory, files, etc...).
    I dont use C++ much these days and usually use C99, but I do miss RAII and find using gotos are fine for a tiered way of deallocating resources, without repeating error handling code and avoiding too much indentation.

    I dont do this stuff for a job and dont have someone standing over my shoulder saying "you should do it this way", so I guess for me they are fine for this purpose

  9. #24
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I dont do this stuff for a job and dont have someone standing over my shoulder saying "you should do it this way", so I guess for me they are fine for this purpose.
    ^_^

    I'd be more likely to fire someone who duplicated the code or moved cleanup into otherwise pointless functions with references to several stack variables instead of the one who used `goto' to do the same job cleanly.

    Soma

  10. #25
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    I heard the goto keyword optimizes the use of the stack on recursive functions. Does someone have an example?
    That depends on what you heard, I suppose. In a function that is tail recursive, you can replace the function call with a goto to the top of the function (after properly updating the variables representing the function's parameters), but then you should also be able to rewrite it using a proper looping construct instead of a goto. The goto/loop will avoid a potential stack overflow, although some compilers are able to do tail call optimization themselves.

  11. #26
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Over the years, I have found that the more restrictive your coding standard is, the better your code gets. Always. If you can't figure out how to avoid a goto in five minutes of thought, then think for ten minutes. If you still fail, think for half an hour more. If your looping structure is immune to getting it right, then throw away the entire structure and begin again.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #27
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by artur View Post
    I heard the goto keyword optimizes the use of the stack on recursive functions. Does someone have an example?
    Nope, but I have converted tail-recursive code to an iterative version tons of times without ever using a goto. Not one of those was difficult enough to make me want to consider using a goto.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #28
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by brewbuck View Post
    Over the years, I have found that the more restrictive your coding standard is, the better your code gets. Always. If you can't figure out how to avoid a goto in five minutes of thought, then think for ten minutes. If you still fail, think for half an hour more. If your looping structure is immune to getting it right, then throw away the entire structure and begin again.
    that's what I did recently when I came across a goto that I used a while back to break out of nested loops. I kept the code (C++), but since I'm using C++11, I wrapped it in

    Code:
    [&](){<nested loop here>}();
    and replaced the goto with a return. it is a very simple solution that leverages the power of some new language features present in C++11.

  14. #29
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Elkvis View Post
    I kept the code (C++), but since I'm using C++11, I wrapped it in

    Code:
    [&](){<nested loop here>}();
    and replaced the goto with a return. it is a very simple solution that leverages the power of some new language features present in C++11.
    Nice technique!
    Thanks.

  15. #30
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by Elkvis View Post
    first of all, a function call is not a goto. not behind the scenes or under the hood or any other idiom you want to use to describe it. every processor I've ever come into contact with has call/return semantics in its machine language. these features are always used when available.
    If the compiler decides to inline the function the generated code will look surprisingly similar to any of the the other flag or goto-based solutions to this problem. No call/return semantics needed.

    I have similar caveats for anyone using the phrase "stack variable" in their reasoning to prefer using goto, but they're more open to debate.
    Last edited by KCfromNC; 06-15-2012 at 07:51 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why is goto bad?
    By DarkAlex in forum C++ Programming
    Replies: 28
    Last Post: 12-02-2007, 11:24 AM
  2. GoTo's?
    By Neo1 in forum C++ Programming
    Replies: 4
    Last Post: 07-09-2007, 03:24 AM
  3. goto
    By chrismiceli in forum C Programming
    Replies: 20
    Last Post: 08-26-2003, 07:19 AM
  4. goto again...
    By volk in forum C++ Programming
    Replies: 4
    Last Post: 04-29-2003, 07:25 PM
  5. Good idea, bad idea.
    By sean in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 06-15-2002, 12:26 PM

Tags for this Thread