• (cs)

    "On Error Resume Next"? Bah, luxury! Back in my day (okay, my very very very early days), all we had was "TRAP line number".

    Actually, that worked pretty damn well for an 8K BASIC. Consider:

    10 TRAP 30 20 disk I/O or whatever:GOTO 40 30 clear trap:check error code:do something 40 PRINT "YAY!"

    VS

    try { disk I/O or whatever } catch(e) { check error code; do something } os.core.util.io.terminal.line.output(String.concatenize("YAY!", os.core.util.io.terminal.localizedLinefeed()), UTF8)

  • Gordon (unregistered)

    This sounds like an echo of some religious war.

    But I will say that I agree that goto's weren't that bad. A little over a decade ago, I was brought in to maintain a C (not C++) program -- actually a suite of programs that used socket-level IPC -- that was maybe a few 100K lines of code. Goto's were common, but only for error handling; for example:

                if (SomethingIsHorriblyWrong) {
                    errorflag = ReallyBadError;
                    goto end;
                }
        ...
    end:
        // cleanup
        ...
        return errorflag;
    
    where the end: label marked any cleanup stuff (deallocating memory, etc) that had to be done before the function could return.

    As someone who had to maintain the code, I was able to quickly and easily understand what the author was trying to do, and why. No spagetti, no artificial branches to get in the way of what's really supposed to happen, only one exit point -- I found it very easy to maintain. Yes, it creates a break in your train of thought, but that's not a bad thing when dealing with errors. It also makes it relatively painless to add even more error checking to the code. Even now, I find that sort of construct simpler (and therefore easier to maintain) than throwing/catching exceptions.

    Goto's can be easily abused -- in fact, I would consider using them in just about any other way to be abuse. But when used as above, I can say from experience it leads to easily-maintained code.

  • Jay (unregistered)

    It seems to me like opposition to GOTOs has become one of those unshakable dogmas that may not be questioned. Someone says, "Look, wouldn't this program be cleaner if we just used a goto here?" And the reply is always, "NO! Gotos are evil! You can avoid using the goto by just writing a hundred lines of incomprehensible code!"

    The question should not be, Is it possible to solve the problem without using a goto? But, Is the goto-less solution the easiest to read and understand?

    With the invention of catchable exceptions and break-label, most of the remaining cases where a goto was useful have evaporated. I've had very few cases in Java where I ever had any desire to write a goto. But there are a few. Yes, I can always get around them by setting flags, moving code into functions, and/or writing huge, deeply-nested IF statements. But sometimes those things suck bigger than goto's.

  • Franz Kafka (unregistered) in reply to Woohoo
    Woohoo:
    ouch...

    you see the same form of abuse in Java a lot: using exceptions for flow control...

    absolutely worst thing I ever saw was this:

    void someMethod()
    {
       try
       {
          ... // ~300 LOC
          if (someExitCondition)
          {
             String s = null;
             s.length();
          }
          ... // ~300 LOC
       }
       catch(Exception ex)
       {}
    }
    

    The developer's worst sins in ascending cruelty:

    1. creating a much too long method body (the whole system was certainly not OO)
    2. not knowing about the "throw" statement and using a dumb deliberate error condition to force an exception
    3. using an empty "catch" block with a generic exception type, thus rendering all real exception handling completely moot in this method
    4. not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    Um, NPE is a RuntimeException - this code won't even work

  • N (unregistered)

    When our programming practical started, the lecturer threatened to let anybody fail the course who would use goto.

  • pmcc (unregistered) in reply to Ian

    Response.Redirect(MyPage.aspx, FALSE);

    Wont throw the ugly exception inside try catch

  • SomeCoder (unregistered) in reply to Gordon
    Gordon:
    This sounds like an echo of some religious war.

    But I will say that I agree that goto's weren't that bad. A little over a decade ago, I was brought in to maintain a C (not C++) program -- actually a suite of programs that used socket-level IPC -- that was maybe a few 100K lines of code. Goto's were common, but only for error handling; for example:

                if (SomethingIsHorriblyWrong) {
                    errorflag = ReallyBadError;
                    goto end;
                }
        ...
    end:
        // cleanup
        ...
        return errorflag;
    
    where the end: label marked any cleanup stuff (deallocating memory, etc) that had to be done before the function could return.

    As someone who had to maintain the code, I was able to quickly and easily understand what the author was trying to do, and why. No spagetti, no artificial branches to get in the way of what's really supposed to happen, only one exit point -- I found it very easy to maintain. Yes, it creates a break in your train of thought, but that's not a bad thing when dealing with errors. It also makes it relatively painless to add even more error checking to the code. Even now, I find that sort of construct simpler (and therefore easier to maintain) than throwing/catching exceptions.

    Goto's can be easily abused -- in fact, I would consider using them in just about any other way to be abuse. But when used as above, I can say from experience it leads to easily-maintained code.

    Umm... ok. I'm maintaining some code that does just this (except it's C++ code, not C). Let me introduce you to a little error, I like to call the "jump to label" error:

    vector<string> someVector;
    
    if (some error) goto end;
    
    // Add elements to the vector here.
    
    vector<string>::iterator begin = someVector.begin(); // This line causes an error because of the goto
    
    vector<string>::iterator end = someVector.end(); // This line also causes the error
    
    ...<snip>...
    
    end: 
       // clean up... etc.
    
    

    Resulting error message (using g++) "error: jump to label 'end' error: crosses initialization of 'vector<string>::iterator begin'

    FAIL.

    I've give you that gotos might have some use... in really obscure situations. But overall, it makes for a maintainability nightmare.

  • tekiegreg (unregistered)

    Heh, it's rare where I need to have a pointless try block, but for some reason in some legacy COM objects within .NET, even though the COM object itself processes everything ok (so it appears), an exception still bubbles up and needs to happen, so you get code that looks like this (forgive me I'm bad at notepad coding):

    Dim a AS New LegacyComObject

    Try

    a.ExecuteComMethod()

    'Why does this code generate this exception even though the method executed just fine and produced the result, very well, just skooshing the error and moving on Catch Ex as COMException

    'Doing nothing

    End Try

  • (cs) in reply to Franz Kafka
    Franz Kafka:
    Woohoo:
    ouch...

    you see the same form of abuse in Java a lot: using exceptions for flow control...

    absolutely worst thing I ever saw was this:

    void someMethod()
    {
       try
       {
          ... // ~300 LOC
          if (someExitCondition)
          {
             String s = null;
             s.length();
          }
          ... // ~300 LOC
       }
       catch(Exception ex)
       {}
    }
    

    The developer's worst sins in ascending cruelty:

    1. creating a much too long method body (the whole system was certainly not OO)
    2. not knowing about the "throw" statement and using a dumb deliberate error condition to force an exception
    3. using an empty "catch" block with a generic exception type, thus rendering all real exception handling completely moot in this method
    4. not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    Um, NPE is a RuntimeException - this code won't even work

    Why not? You can catch RuntimeExceptions, and RuntimeException is a subclass of Exception.

  • fraserofthenight (unregistered)

    When porting a C++ app to Java, I ended up using the following happy construct more than once:

    private static class GotoL1 extends RuntimeException { }
    private static final GotoL1 GOTO_L1 = new GotoL1();
    
    void method
    {
      try
      {
        // ... 50 or so LOC
        if(someCondition)
            throw GOTO_L1;
        // ... 50 more LOC
        throw GOTO_L1;
      }
      catch(GotoL1 ex) { }
      // Stuff from where the L1 was in the C++ code...
    }
    

    I tried to avoid this as much as possible because it can kill performance, but there were quite a few gotos around.

  • (cs) in reply to Steve
    Steve:
    Woohoo:
    4) not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    There are some schools of thought which abjure the use of
    return
    statements other than as the last line of a function or method.
    IMO an absolutely idiotic paradigma, and quite possibly the original reason for today's WTF.
  • (cs) in reply to KenW
    KenW:
    T:
    Exceptions are not only meant for error handling, it's a useful mechanism built into the language.

    They're not meant for normal things, either. They're called "exceptions" for a reason. They're to handle exceptional things - things that you don't expect to happen during normal execution. Things like hard-coded redirects because conditions aren't met isn't unexpected; obviously you DID expect them, because you wrote the code to handle them with the exception. Handle them the correct way instead.

    Using exceptions to do things you expect is stupid.

    According to that line of reasoning, any kind of code that handles specific exceptions is stupid, because it obviously expects that exception, so the exception should not have been used.

    IMO the correct way to decide when to use exceptions and when not to is not by looking at "expected vs. unexpected behaviour", it's by "local vs. global handling". Exceptions have the unique property of propagating up the stack and thereby allowing you to write global, generic error handling code without having to call it explicitly, and to override it with more specific error handling code where necessary.

    This means the code is a WTF not because it uses exceptions to do something non-exceptional, but because it uses exceptions for local flow control within a method.

    Of course, both criteria correlate - global, generic error handling is pretty much the only thing you can do about completely unexpected stuff.

  • (cs) in reply to brazzy
    brazzy:
    paradigma
    Nice! A blend of paradigm and dogma, perhaps? I know of its existence in other languages, but you're using English.
  • (cs) in reply to Matt
    Matt:
    OzPeter:
    Joe Scylla:
    Well, goto got stigmatized and now many are using Exceptions for flow control (and sometimes write better readable code).

    Goto wasn't that bad.

    What I find ironic is the the aboslute belief that Goto's are bad, yet when you get down to the bare metal thats fundementally what a CPU runs on.

    Like all things Goto's are a tool, and its the misuse of the tool that is bad, not the tool itself (damn am I starting to sound like an NRA spokesperson???)

    GOTOs don't kill applications- Programmers kill applications.

    FYI: GOTOs suffer same problems as guns. Sure they themselves don't kill programs, just as guns themselves don't kill people, but controlling how and when to use them is a major issue, and in most cases better solutions exist but are unused because of the blind use of goto/guns. And by the time that is figured out its too late and you have spaghetti code/massacre.

  • Iago (unregistered)

    I'm fed up of the claim that "you shouldn't use exceptions for control flow because exceptions are supposed to be exceptional". That's like saying "you shouldn't use read-only variables because variables are supposed to be variable".

    That which we call a variable by any other name would still be a name bound to a value that might or might not be mutable. And that which we call an exception by any other name would still be a structured, highly-constrained form of goto with the ability to propogate arbitrary data up the call stack to the first relevant handler.

    Look at what a construct does and how it affects code maintainability, not what English words its name resembles.

  • Woohoo (unregistered) in reply to Franz Kafka
    Franz Kafka:
    Woohoo:
    ouch...

    you see the same form of abuse in Java a lot: using exceptions for flow control...

    absolutely worst thing I ever saw was this:

    void someMethod()
    {
       try
       {
          ... // ~300 LOC
          if (someExitCondition)
          {
             String s = null;
             s.length();
          }
          ... // ~300 LOC
       }
       catch(Exception ex)
       {}
    }
    

    The developer's worst sins in ascending cruelty:

    1. creating a much too long method body (the whole system was certainly not OO)
    2. not knowing about the "throw" statement and using a dumb deliberate error condition to force an exception
    3. using an empty "catch" block with a generic exception type, thus rendering all real exception handling completely moot in this method
    4. not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    Um, NPE is a RuntimeException - this code won't even work

    Um, at least in Java "RuntimeException extends Exception" - therefore "Exception" is the most generic of the user-catchable exception types, so this is a catch-all and does definitely work.

    The most generic type in the whole exception hierarchy is "Throwable", which is the superclass of "Exception" and "Error" - the latter demarcates all conditions which are not user-catchable (though some of them can technically be caught, but it is not advisable to do so: "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch." - from the JSE 5 API docs)

  • (cs) in reply to FredSaw
    FredSaw:
    brazzy:
    paradigma
    Nice! A blend of paradigm and dogma, perhaps? I know of its existence in other languages, but you're using English.
    Do you speak a foreign language? If so, is it related to your native one? If so, have you never made mistakes in the foreign language based on similarities between the two?

    Unless you can honestly answer "Yes" to all three questions: [image]

  • Bill (unregistered) in reply to me

    Well that was a pretty weak response, as others have noted...

    But if you think having an idea for a different use for a tool renders one unfit to program you should probably head back to ITT... of course that you didn't quote the second half indicates that this is just a troll.

    Shit, I am responding to a troll, and not a bright one at that.

  • Woohoo (unregistered) in reply to Steve
    Steve:
    Woohoo:
    4) not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    There are some schools of thought which abjure the use of
    return
    statements other than as the last line of a function or method.

    and

    ThePants999:
    Woohoo:
    4) not knowing about the "return" statement (!!!)

    number 4 is the real killer, of course... ;o)

    Our coding standards prohibit the use of "return" anywhere but the end of a method, the theory being that it's harder to read the method as a whole if you can jump out from anywhere. (We do allow "break" though, and in C you can use "goto EXIT_LABEL" - go figure.)

    Perhaps this has (or rather had) a point in older procedural languages, where functions tended to have hundreds of LOC (whether this was good practice there is still debatable though...)

    But in OO such monsters of LOC ;o) are definitely bad practice and a design flaw. If a method body fits on one screen most of the time, I do not see a problem in using more than one exit point (i.e. "return" statement).

    This is IMHO much better than resorting to complex conditionals ("if/else") to achieve the same effect - or even worse, coming up with perverted abominations like the original WTF or the one I was showing in my first post.

    It might well be that such coding standards lead to such insane constructs in the first place, because the coder can not come up with an implementation that avoids return statements in the middle of the method body without the use of "goto" - so he creates his own "goto" by misusing other language constructs.

  • Anon Barbarzyńca (unregistered) in reply to SomeCoder
    SomeCoder:
    Umm... ok. I'm maintaining some code that does just this (except it's C++ code, not C). Let me introduce you to a little error, I like to call the "jump to label" error:
    vector<string> someVector;
    
    if (some error) goto end;
    
    // Add elements to the vector here.
    
    vector<string>::iterator begin = someVector.begin(); // This line causes an error because of the goto
    
    vector<string>::iterator end = someVector.end(); // This line also causes the error
    
    ...<snip>...
    
    end: 
       // clean up... etc.
    
    

    Resulting error message (using g++) "error: jump to label 'end' error: crosses initialization of 'vector<string>::iterator begin'

    FAIL.

    I've give you that gotos might have some use... in really obscure situations. But overall, it makes for a maintainability nightmare.

    Umm, no. It's just C++ that sucks ;) Seriously though, the OP used C where the idiom is fairly popular (see the Linux kernel source) and is a sort of hand-coded RAII. I actually see nothing wrong with it and use it myself.

    And yes, I also use exceptions for breaking out of 10 functions deep when rendering an HTTP response. So there.

  • Woohoo (unregistered) in reply to FredSaw
    FredSaw:
    brazzy:
    paradigma
    Nice! A blend of paradigm and dogma, perhaps? I know of its existence in other languages, but you're using English.

    Actually, english is not very consistent in that regard. The original forms are "paradigma" (lat.) / "paradeigma" (gr.) and "dogma" (lat./gr.), but the "a" ending was only dropped in "paradigm".

    The word "paradigm" was obviously assimilated earlier and more thoroughly, which is also evident from the plurals: I've only ever seen "paradigms" (never the greek "paradigmata") in english, but for dogma, both forms exist ("dogmas" and "dogmata").

    In german on the other hand, paradigm is used in the original greek form "Paradigma" and both plural forms exist, the germanised "Paradigmen" or "Paradigmas", and the greek "Paradigmata" (which is in a way considered more academic).

    The very same holds true for "Dogma" (pl. "Dogmen" or "Dogmas" and "Dogmata").

  • TopicSlayer (unregistered)

    We have reinvented goto over and over such that we may stop using goto. But, if all you got was goto and used it with a brain then it is no more evil than the constructs which have since replaced it.

    But, let's see what they are:

    1. Exceptions; break the flow of the code too, do you get them? Goto exeception_block and catch (exception) look a lot alike. The only difference is one propogates up the stack. Of course, the benefit of this is that we get to play a nice game of "who is really going to catch that exception". Who knows, who cares, some one will...maybe...or maybe the app will die.... Whatever...no big deal. By the time it gets back to the handler, though, what state was the app in when it got thrown? How many stack levels did we skip on through before we got it? I dunno...who cares, doesn't matter. Of course, half those questions you don't have to ask if you use exceptions right...but how many coders do that?

    2. Private functions; yeah, goto fn_name and fn_name() just slay me with their differences. The only large difference is I can rescope all the variables I need in the function. At least that constrains what part of the local stack the "goto" private function can touch.

    3. Loop break/continue; well at least we have named loops and the ability to specify which one we want to break or continue...oh wait, that's...goto! Restricted, obviously, to the bottom/top of a loop.

    4. Nested if/else, additional state variables, etc; yeah, much better solutions. I like making sure the flow of my code is controlled with constructs having a McCabe complexity that reachs the far end of a 32 bit integer. Even better to thrown in state variables that say (doThisLater = true) and make sure I test that somewhere outside my if. This is even better when it says (pleaseDoSomething = magic_number) and check it with a case. And, while I do not know if goto could have saved us here, certainly we could have structured the code better?

    Point is, spaghetti code is spaghetti code regardless of the constructs you use. If you write spaghetti, you will do it whether or not you have goto to aid you.

    P.S. Style debates are always so much fun. Especially when they degenerate to name calling and intarweb arm wrestling.

    Can someone please get me some popcorn? I can't wait for the real show to begin. It may even be as good as that Stalone movie...what was it..."Over the Top?"

  • dolor (unregistered) in reply to Claxon
    Claxon:
    But you have to agree that they are intended to be used for exceptional circumstances.

    Absoultely not. This attitude makes exceptions seem like they're supposed to be used very rarely - so people still use return codes and other half-baked ideas instead of elegant exceptions.

    Running to the end of a file is perhaps not 'exceptional' but is much cleaner to deal with. The supposed overhead in dealing with exceptions is, for the vast majority of situations, dwarfed by the extra cost and confusion in writing hacky stupid code.

    Aside: Gotos are bad because they allow for multiple ENTIRES to a code block. Exceptions only allow for multiple EXITS.

  • (cs) in reply to brazzy
    brazzy:
    Do you speak a foreign language? If so, is it related to your native one? If so, have you never made mistakes in the foreign language based on similarities between the two?
    That's why I like reading your posts so much, brazzy. You're such a positive, upbeat kind of guy.

    The only insult in my words was the one you conjured in your mind. I was complimenting you on what I thought was a slick bit of wordplay. But alas, as you say, it was not, and the mistake was mine in perceiving it to be so.

  • TopicSlayer (unregistered) in reply to dolor
    dolor:
    Claxon:
    But you have to agree that they are intended to be used for exceptional circumstances.

    Absoultely not. This attitude makes exceptions seem like they're supposed to be used very rarely - so people still use return codes and other half-baked ideas instead of elegant exceptions.

    snip

    Aside: Gotos are bad because they allow for multiple ENTIRES to a code block. Exceptions only allow for multiple EXITS.

    Point 1) what is an elegant exception? One that emulates a "return code"? I would presume any "return code" that is not "success" is, therefore, an excpetion and therefore exceptional because you generally want everything to succeed.

    Point 2) WHAT? I can enter an exception block from anywhere (even outside the current stack frame) that a throw occurs. If that's not more than one entry into the exception block, I don't know what is. Hell, that is like a long jump. It does, however, have a single exit off the end of the exception handler unless you rethrow and start the mess again.

    Aside:

    Do we like things like:

    try { obj.fn_that_may_not_succeed(arg1, ...); } catch { ... any exception that the fn may throw. }

    try { obj.another_fn_that_may_not_succeed(arg1, ...); } catch { .. etc }

    over and over? Because that looks a lot like:

    if ((failure_code = obj.fn_that_may_not_succeed) != success) { /* check failure_code and handle */ }

    with just a little more state that comes along for the ride with the exception. And, while this state is certainly nice to have, the code still conveys the same logical concept.

  • (cs)

    Seriously, this isn't a big WTF. I work with legacy exception handling code that does conditional string checks on the exception message (e.getMessage().startsWith("blah")) to decide how to handle the exception. Hannes should come back when he learns pf the true pain of badly used and abused exceptions.

  • SomeCoder (unregistered) in reply to Anon Barbarzyńca
    Anon Barbarzyńca:

    Umm, no. It's just C++ that sucks ;) Seriously though, the OP used C where the idiom is fairly popular (see the Linux kernel source) and is a sort of hand-coded RAII. I actually see nothing wrong with it and use it myself.

    And yes, I also use exceptions for breaking out of 10 functions deep when rendering an HTTP response. So there.

    So why not just wrap that in a function rather than use gotos? I'm really not trying to be argumentative, I want to know what you think about doing something like this:

    void cleanup(char* someData, char* moreData)
    {
        // clean up here, delete, delete[] etc.
    }
    

    Then just calling that instead of the goto. Sure, it's one extra line of code that says:

    cleanup(myVar, someOtherVar);
    return; // extra line of code.
    

    but to me that's far more readable and way easier to maintain than the previous example using goto. Adding more variables can be "harder" than just using goto but the end results are worth it in my opinion. If you really hate adding more params, just use a struct.

    Of course, the real way would be to use RAII with exceptions but sometimes you're stuck looking at the abomination of code that I'm currently trying to figure out. Or you're using straight C.

  • SomeCoder (unregistered)

    Oh and I should say that adding that "return;" there might be against some people's religion/coding standards but I've never had a hard time with functions that have multiple exit points. It could be argued that they are evil but that's not the discussion I'm going for right now :)

  • (cs) in reply to SomeCoder

    Wow, the performance of that webapp must be awesome: every time the user requests a new page an exception is thrown, which then has to be caught and GC'd! Apparently, the guy who wrote that code doesn't know about using string variables...

    If I ever find someone who writes code like that, I will beat them to death with a .NET reference book. (Those things are heavy, y'know.)

    Aside:

    I work for a programming house that is moving from Delphi/Object Pascal (insert sound of puking) to .NET, and one of the coding standards was "thou shalt not use return in multiple places in a method".

    Thankfully, the guys in charge aren't morons and after I provided some examples of how using return early can make code easier and more logical to read, they agreed to change the standard :D.

  • Jon (unregistered)

    This is why we should all be using call/cc.

  • (cs)

    GOTOs are alright. if you use a FlowChart. Add a noodle. and Jam IT.

  • Konrad (unregistered)

    For me the most compelling reason not use exceptions for flow control (at least in python) is that It is slower, and I have done the profiling to prove it.

    I used it a fair bit in code which turned out to be cpu intensive, so we came to the profiling stage. replacing try ... except blocks with if ... else blocks was the single largest speedup we managed to achieve, anything else would have required moving logic from python to C.

  • Tordek (unregistered)

    Whay, haven't you heard of the DRY principle? He doesn't repeat the redirection code that way!

  • Greg (unregistered)

    This is why I hate goto's - bad programmers see them and think can and should be used in places where other constructs would work perfectly.

    My current employer has a ton of legacy vb and asp/vbscript code written either by bad programmers in the past, or by current Indian programmers (I assume there are good programmers over there, but my company doesn't seek them out, if it could even recognize them if it tried). Either way I've seen goto's abused all over the place, and I assume if they could use exceptions they would abuse them as well.

    Recently someone asked me to help bring them up to speed with .Net, and I remember specifically telling them "If you use exceptions to handle logical conditions I will submit your code to TDWTF" :)

  • lsutiger (unregistered) in reply to Matt

    The goto function was made for procedural programming. With the advent of object oriented and event driven programming, there is no need for the goto statement. Then again, some would say writing a procedural program in C# is pure evil. But I do write small 'scripts' in C# from time to time that are completely procedural. As long as you are not abusing the language and your program is efficient, go for it. But, I will never use the goto statement in my C# code.

  • Real Programmer (unregistered) in reply to Matt

    GOTOs don't kill applications- Programmers kill applications.

    Actually, we have users to do that for us.

  • (cs)
    fwef:
    *spam*
    jherrh:
    *more spam*
    jheh:
    *more spam*
    lk:
    *yet more spam*
    If someone will figure out this guy's physical location, I'll chip in on hiring a hit man.
  • Jimmy (unregistered)

    Actually I've used a similar pattern myself on a few occasions. Its not really that bad.

  • iNFiNiTyLoOp (unregistered)

    A while ago I wrote some FastTracker (*.xm) playback routine that seemed to need goto. FastTracker can play back sounds in different modes, one of them being ping-pong. Ping-pong will alternate between forwards and backwards playback, reversing direction between the loop points.

    if( irreleventMode1 ){ //...
    }else if( irreleventMode2 ){ //...
    }else if( pingPongForwardsMode ){
      pingPongForwards:
      while( playbackPosition < endOfLoop ){
        Add sample from playback position to the buffer;
        increment playback position.
        if( buffer is full ) return;
      }
      goto pingPongBackwards;
    }else if( pingPongBackwardsMode ){
      pingPongBackwards:
      while( playbackPosition >= beginningOfLoop ){
        Add sample from playback position to the buffer;
        decrement playback position.
        if( buffer is full ) return;
      }
      goto pingPongForwards;
    }
    

    Okay you goto haters, how would you refactor this? (It could ping-pong many thousands of times a second, so recursion is out.) These are the only two gotos in the program.

  • Jimmy Jones (unregistered) in reply to Matt
    Matt:
    What I find ironic is the the aboslute belief that Goto's are bad, yet when you get down to the bare metal thats fundementally what a CPU runs on.

    The "GOTOs are bad" thing comes from a time when you could GOTO any line in the entire program. I remember people taking advantage of this often (including me).

    GOTOs within small procedures are ok I guess. I think x86 CPUs have a range of 128 bytes for a conditional jump. If only there was a way to enforce that at high level...

  • GOTO lover boy (unregistered)

    Hey, Response.Redirect is the GOTO of the 21st century...

  • Mike C (unregistered) in reply to Matt

    I am currently ordering a t-shirt to that effect :)

  • AdT (unregistered) in reply to Ian
    Ian:
    he probably did this because .Net throws an exception if you do a redirect inside a try block.

    That's correct but misleading. Redirect(string) always throws ThreadAbortException, no matter whether you're in a try block or not (how would ASP.NET even know you're using a try block, and why should it care?). This is not a problem, it's by design. The problem is that many programs use a "catch (Exception ex)" in conjunction with this try, and the given handler then does things that are inappropriate for the ThreadAbortException thrown by Redirect. So one easy solution is to check whether the caught exception is a ThreadAbortException, and if so, rethrow it without any further processing. Alternatively, if you just do nothing in the handler, .NET will automatically rethrow the exception for you. As a side note, the correct way to rethrow the exception "ex" from inside the handler that caught it is "throw;", not "throw ex;", dear naughty stack trace smashers.

    We now have two possible solutions to the above-mentioned problem, both of which make more sense than throwing the custom exception seen in the CodeSOD.

  • (cs) in reply to Joe Scylla
    Joe Scylla:
    NiceWTF:
    ...snipped...

    That is at least my understanding of the main point in the famous goto considered harmful paper.

    Some people also raise their voice for goto: Code Complete 16.1 Using gotos An Argument for the Use of goto Statements

    imho the best summary about the use of goto:

    Use of gotos is a matter of religion. My dogma is that in modern languages, you can easily replace nine out of ten gotos with equivalent structured constructs. In these simple cases, you should replace gotos out of habit. In the hard cases, you can still exorcise the goto in nine out of ten cases. In these cases, you can break the code into smaller routines; use nested ifs; test and retest a status variable; or restructure a conditional. Eliminating the goto is harder in these cases, but it's good mental exercise, and the techniques discussed in this section give you the tools to do it.

    In the remaining one case out of 100 in which a goto is a legitimate solution to the problem, document it clearly and use it.

    The code used as a counter-example to the popular argument "GoTos are evil" contains lots of return statements which is just even more horrible than a "basic GoTo usage".

    So yes, in this case GoTos look better then millions of return statements... So What ?

  • Chris G (unregistered)

    I must confess I am happy with using goto. I mean when writnig embedded code with only a main(), why not use a goto? It's efficient and effective.

    As with all things everything has it's place and shouldn't be ruled out!

  • rainer (unregistered) in reply to BadReferenceGuy
    BadReferenceGuy:

    What I find ironic is the the aboslute belief that Goto's are bad, yet when you get down to the bare metal thats fundementally what a CPU runs on.

    Like all things Goto's are a tool, and its the misuse of the tool that is bad, not the tool itself (damn am I starting to sound like an NRA spokesperson???)

    I direct you to Dijkstra: http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF

    He had very specific reasons why he considered goto to be a bad idea.

    Goto is used quite frequently in the Linux kernel, because it allows very clean, readable code if you have to cleanup (locks, memory, ...) after an error. See this discussion on the kernel mailing list, where you can find the following excellent example:

    	do A
    	if (error)
    		goto out_a;
    	do B
    	if (error)
    		goto out_b;
    	do C
    	if (error)
    		goto out_c;
    	goto out;
    	out_c:
    	undo C
    	out_b:
    	undo B:
    	out_a:
    	undo A
    	out:
    	return ret;
    
  • (cs) in reply to TopicSlayer
    TopicSlayer:
    Point 1) what is an elegant exception? One that emulates a "return code"? I would presume any "return code" that is not "success" is, therefore, an excpetion
    The problem with return codes is that they are ignored per default (i.e. you have to write extra code to handle them, otherwise they are ignored), whereas exceptions cannot be ignored without writing extra code.

    And of course, passing return codes up the stack is a pain in the ass, whereas exceptions propagate up the stack automatically.

  • vanjalolz. (unregistered) in reply to Matt
    What I find ironic is the the aboslute belief that Goto's are bad, yet when you get down to the bare metal thats fundementally what a CPU runs on.
    Humans aren't machines. We aim to write readable code, and generally gotos make for very hard to follow code.

    CPUs don't have any understand of 'classes' or scripting languages, yet we still use them for development.

  • (cs) in reply to OJ
    OJ:
    FredSaw:
    Back in the pre-dotnet days I worked at a company which used VB as our development language. Its only built-in error trapping was by means of "On Error Goto [label]".

    Well, there was also "On Error Resume Next". I have seen code that actually used it. It was awful.

    Actually, that's how you performed exception handling in classic ASP (VBScript): You use "On Error Resume Next" prior to a statement that could generate an exception, then check the global Err object for errors. So something like:

    On Error Resume Next
      DbConn.Connect()
      If (Err.Count > 0) Then
         '  Perform error handling
      Else
         ' Continue as normal
      End If
    On Error Goto 0
    

    Is akin to this in a "better" language:

    Try
      DbConn.Connect()
      ' Continue as normal
    Catch
      ' Perform error handling
    End Try
    

    It's just more primitive and limited (and convoluted). The surprising thing is that so many people just used "On Error Resume Next" to absolutely ignore the error. That's not only bad practice, that's just plain stupidity and ignorance.

    -dZ.
    
  • (cs) in reply to AdT
    AdT:
    So one easy solution is to check whether the caught exception is a ThreadAbortException, and if so, rethrow it without any further processing. Alternatively, if you just do nothing in the handler, .NET will automatically rethrow the exception for you.

    Or, an easier (and may I say, better) solution is to send "False" as the second argument to Response.Redirect() which will prevent the thread from being aborted, and code properly your exit path.

    -dZ.
    

Leave a comment on “The RedirectException”

Log In or post as a guest

Replying to comment #:

« Return to Article