Thread: I used my first goto statement today!

  1. #16
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I think you're mixing up my "null reference" and "unchecked return value throws exception" experiments.
    O_o

    No.

    This:

    Code:
    try{throw Something();}
    catch(const Something & e){if(e){/* real exception */}else{/* control flow exception */}}
    was a thing you posted.

    Which is just one of the several times when a few regulars explained how exceptions aren't flow control constructs.

    Exceptions may great control flow constructs.
    You are only misusing the exception mechanism to control flow to pacify claims against `goto'.

    You are just hiding one bad decision, pun a bad hack instead of fixing the code, with another in the hopes no one notices.

    *shrug*

    Well, you fooled anduril462 who doesn't know C++ all that well.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    So instead of using goto in a proper, structured manner, you've resorted to breaking up a loop in a completely unnatural way (nevermind the issue of having clean access to variables from the calling function)?
    I disagree. I find anduril462's example to be natural, idiomatic C++. Your version with goto to break out of nested loops (or in MutantJohn's case, a switch within a loop) is okay since the label comes at the end so it becomes a known idiom from C, but I would normally prefer anduril462's version because of the abstraction involved. MutantJohn's version with goto, on the other hand, I don't like because the label comes before the inner loop. Yes, it is somewhat of a continue, but it also more unusual and hence harder to understand.

    Quote Originally Posted by Sebastiani
    In any case, I don't see how throwing an exception is such a "poor" choice. Exceptions make great control flow constructs.
    Stroustrup disagrees: What shouldn't I use exceptions for?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Well, if my code is harder to understand, it's literally because I have no idea what I'm doing XD

  4. #19
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    phantom, the reason why a goto was used was because it was a simple solution to integrate and yes, it's pedantic. I can't imagine using a non-ISO compliant compiler. People know g++ is free, right? Also, if a goto was the bane of all existence then why did the developers spend time creating it?
    O_o

    Yeah, I know why you used `goto'. Fixing a hole with spackling paste is massively simpler than rebuilding the house.

    I have no problem throwing away thousands of lines of code, but then, I'm obviously insane.

    However, I can easily how you wouldn't want to start another rewrite after having just finished a rewrite.

    Also, the "ISO-compliant compiler" thing is a "red herring". You could use `goto' with `if' instead of `while', but that doesn't make it the best choice. If the story of a better approach offends you, you should seek a different profession. The people in this thread aren't calling you out as a bad programmer for using the method as you have; we are only telling you of a more sophisticated method. Yes, we know, "GCC" is free. Yes, we also know, more or less, why `goto' is available to C++. We also know that this isn't a good fit for `goto' because the alternative method produces code that is much cleaner.

    [Edit]
    Here "cleaner" is meaning "more canonical", "more idiomatic", and "more natural to C++" making it, as laserlight implies, easier to understand for other C++ programmers.

    You are using this code, indirectly, for you resume, yes? Well, a great C++ programmer reviewing your example code for the sake of interview wants to see code that he/she instantly recognizes as good C++ that other programmers working for the company can readily maintain.
    [/Edit]

    Soma
    Last edited by phantomotap; 10-16-2013 at 01:20 AM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #20
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by MutantJohn View Post
    I'd also like to mention that if I was immediately fired for using a goto without being told to at least go back and rewrite my code then that'd be a very stressful job.

    phantom, the reason why a goto was used was because it was a simple solution to integrate and yes, it's pedantic. I can't imagine using a non-ISO compliant compiler. People know g++ is free, right? Also, if a goto was the bane of all existence then why did the developers spend time creating it?

    I think the first reply in this thread was right. It's not the best use of a goto but it's not bad. It doesn't break my code and for once, I can actually triangulate 8000 points whereas before I couldn't triangulate 4000 not using goto as a means of iteration. I like using goto in this context because it doesn't obfuscate my code from what it was before. Now, I will look into the use of stacks but in the meantime, a goto seems to suffice just fine. I will analyze the time it would take to rework the structure of my code and see if it's exactly that much better of an implementation to use stacks.

    Also, my code really looks likes this :
    Code:
    for (auto it = fract.begin(); it < fract.end(); ) {
    
       test :
    
       tetra *t = *it;
    
       for (int i=0; i<4; i++) {
    
          if (t->ngb[i]) {
    
              auto distance = std::distance(fract.begin(), it);
    
              switch (x) {
    
                   case 23 :
    
                         if (two_to_three(fract, inherit, t, t->ngb[i], plane, x, y) == 0)
                            it = fract.begin() + distance;
                         else
                         it++; 
                         if (it >= fract.end()) return;
    
                        goto test;
               }
          } if (i == 3) it++;
       }
    }
    This way, it's a bit more clear to see what I'm doing. I don't know... A goto was a simple solution to a problem that presented itself and so far, my code seems stable. You can use non-compliant compilers all you want and I'm not guaranteeing that my code will work. But as far as I can tell, the -pedantic flag is silent during compilation so it's ISO cleared and if you're compiler isn't ISO compliant then whose fault is that? I can't write for every possible scenario or odd compiler you use. Hopefully the VB compiler is ISO compliant...
    Well, let me just say that while using goto to break out of a loop is acceptable (IMO), the way in which you are using it is arguably just the sort of practice that has led to it's marginalization as a language feature! The reason being is that you can easily fall into the pitfall of structuring more and more of your code around such constructs (ie: spaghetti code) and pretty soon only you and God (or maybe just God) can follow it. More specifically, jumping to code ABOVE is generally considered bad practice, whereas DOWNWARD is okay ONLY IF THERE IS NO OTHER ROUTE. In most cases, gotos are reall not necessary in the first place...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #21
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by MutantJohn View Post
    I think the first reply in this thread was right. It's not the best use of a goto but it's not bad. It doesn't break my code and for once, I can actually triangulate 8000 points whereas before I couldn't triangulate 4000 not using goto as a means of iteration. I like using goto in this context because it doesn't obfuscate my code from what it was before. Now, I will look into the use of stacks but in the meantime, a goto seems to suffice just fine. I will analyze the time it would take to rework the structure of my code and see if it's exactly that much better of an implementation to use stacks.
    I think we're all in agreement that you'd be better off without the goto.

    Quote Originally Posted by MutantJohn View Post
    This way, it's a bit more clear to see what I'm doing. I don't know... A goto was a simple solution to a problem that presented itself and so far, my code seems stable.
    Yes, it was a simple solution. Treat it as a proof-of-concept. You know you can do this iteratively. Now, refactor to make your iterative approach even better.
    Quote Originally Posted by MutantJohn View Post
    You can use non-compliant compilers all you want and I'm not guaranteeing that my code will work. But as far as I can tell, the -pedantic flag is silent during compilation so it's ISO cleared and if you're compiler isn't ISO compliant then whose fault is that? I can't write for every possible scenario or odd compiler you use.
    Don't make the assumption that "compiles" means it "works". Even if it compiles with no errors or warnings on the strictest settings, with -pedantic. Take for example, code that compiles cleanly, but has a null pointer bug. When you compile with the -pedantic flag, it is telling the compiler to check the source code for strict ISO compliance: does it adhere to all the rules on source code, and does it avoid the use of any extensions. Nobody is saying that what you wrote, the C++ source code, isn't ISO compliant. What phantom is saying is that, under some complex uses of goto, the compiler will turn your syntactically valid C++ code into machine code that doesn't quite behave the way it ought to (specifically in properly calling the destructors of objects that fall out of scope when the goto is executed). Basically, the compiler tries to do the right thing, but doing the right thing in that case is difficult, and most compilers do it wrong. Consider it a bug in the compiler.

    And you don't have to cover every "odd" compiler, but you certainly can avoid writing code that most compilers will screw up. Compilers are imperfect, that's life in the real world.

  7. #22
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    And you don't have to cover every "odd" compiler, but you certainly can avoid writing code that most compilers will screw up. Compilers are imperfect, that's life in the real world.
    ^_^

    @MutantJohn:

    Okay. Well, anduril462 said that beautifully so I couldn't possibly add anything meaningful to it, but I'm going to add some context all the same.

    I offer this context for a simple reason: don't start thinking you'll get to pick your tools forever.

    Now, you may be surprised, but a lot of the regulars here don't even do C++ for a living. Those that do or have done can tell you, a lot of C++ houses will have you throwing code at multiple compilers. (You should ask grumpy for I think he has such work.) You aren't going to get by with just "G++". The point is, you may very well be expected to compile code that works despite the quirks of several different compilers.

    I wish I could have said it, I wish I could say it better, but I can't so I'll just quote it again "And you don't have to cover every "odd" compiler, but you certainly can avoid writing code that most compilers will screw up. Compilers are imperfect, that's life in the real world.".

    Let me tell you MutantJohn, that's a bit of truth you can take to the bank.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  8. #23
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    I disagree. I find anduril462's example to be natural, idiomatic C++. Your version with goto to break out of nested loops (or in MutantJohn's case, a switch within a loop) is okay since the label comes at the end so it becomes a known idiom from C, but I would normally prefer anduril462's version because of the abstraction involved. MutantJohn's version with goto, on the other hand, I don't like because the label comes before the inner loop. Yes, it is somewhat of a continue, but it also more unusual and hence harder to understand.
    Well, I do agree with you on his placement of the goto label (not present in his original post, see my response later), but insofar as breaking out of a loop I see it as a non-issue; the goto is the most logical choice. That said, the fact that it is more often than not used incorrectly (as demonstrated by the OP's proposed solution), I humbly cede the floor to you on this one.

    Quote Originally Posted by laserlight View Post
    With all due respect, AFAIK that's based solely on someone's personal opinions/tastes concerning the "proper" use of exceptions, and as such I could care less.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #24
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Ooooookay.

    I like this quote the most from andy :
    Yes, it was a simple solution. Treat it as a proof-of-concept. You know you can do this iteratively. Now, refactor to make your iterative approach even better.
    I will re-do my code. I was wondering if I even could translate it iteratively and I'm thrilled that it works.

    Thank you all for your constructive advice.

    Not gonna lie, it's kind of a lot to take at once. Between this and the resume thread, it looks like I have my work cut out for me. I think I wanna do this. I really think I do. Sorry, telling me that I'll be instantly fired does NOT help me. It just scares me and makes me feel bad. I felt threatened and like I was being dismissed. You may not believe it, but it's tough making up for all the years I wasn't taking computer science when I should've.

    But I didn't count on loving programming as much as I do. I went to college thinking that I loved physics and I really do/did. I love E&M and QM is awesome. But I didn't have the drive to study for the physics GRE as well as I should've and when I started to read about how simulations worked, it opened up this whole world.

    So I never took as much CS as I should've (just lower division stuff) so for me, this is all intimidating and scary. I get what you're trying to do though, phantom. I feel like you're trying to push me. You're trying to actually help me become a professional programmer. Thank you. That means a lot to me.

    And that goes for all you others to. You're basically my education, even if you're not employed as programmers. You're all better than me and I thank you for your advice and guidance. It's very humbling and I know that learning to do things the right way is better for me in the long run and that if I truly have the discipline and pride, I will not use a goto.

    Now, I gotta focus on getting a j.o.b. which will most likely be data entry/analysis for the time being. Also, can you believe I was told I didn't have enough experience to be a dishwasher? What a world we live in today.

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    not present in his original post
    It is present as stated within the text in post #1: "I just put a label or w/e before my int for-loop". I have no clue what does "w/e" mean though. Hmm...

    Quote Originally Posted by Sebastiani
    With all due respect, AFAIK that's based solely on someone's personal opinions/tastes concerning the "proper" use of exceptions, and as such I could care less.
    That someone happens to be the designer and original implementer of C++, and one of the key people on the standard committee when exceptions were standardised in C++. It seems like you did not read the two reasons that were provided:
    • not idiomatic in C++: confuse most C++ programmers used to seing exceptions used only for error handling.
    • slow: deliberately not supported well by C++ implementations (those implementations are optimized based on the assumption that exceptions are used for error handling)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #26
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    It is present as stated within the text in post #1: "I just put a label or w/e before my int for-loop". I have no clue what does "w/e" mean though. Hmm...
    Okay, well it wasn't stated clearly at least.

    Quote Originally Posted by laserlight View Post
    That someone happens to be the designer and original implementer of C++, and one of the key people on the standard committee when exceptions were standardised in C++. It seems like you did not read the two reasons that were provided:
    • not idiomatic in C++: confuse most C++ programmers used to seing exceptions used only for error handling.
    • slow: deliberately not supported well by C++ implementations (those implementations are optimized based on the assumption that exceptions are used for error handling)
    It's a language, not a religion. I reserve the right to use it as I see fit.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #27
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    It's a language, not a religion. I reserve the right to use it as I see fit.
    Certainly, but I note that you have not addressed the reasons given, and merely stuck to your proclamation that "exceptions make great control flow constructs" as if it were infallible dogma
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #28
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Sorry, telling me that I'll be instantly fired does NOT help me.
    O_o

    I fear you misunderstood the context of the "fired" comment, and for that, I apologize.

    I reread it now, and I can see how you thought I was attack you.

    I was attacking the code example I quoted which wasn't even suggested by you.

    The code I attacked is intentionally and knowingly misusing a feature of the language to the detriment of maintainability.

    (Yes, Sebastiani absolutely knew where exception as flow control was headed. We've had this exact argument before. Yes, the same players. I'd be surprised if he hadn't expected the Stroustrup link from laserlight.)

    There is a huge difference between writing code that just needs some fixes and purposefully writing code that other programmers will find difficult to maintain for whatever reason.

    You know, let me elaborate to eliminate any remaining confusion:

    You say that you are going to explore the suggestions as offered. In other words, you are, I expect, going to try and refactor the code and learn from the experience so that you might, in the future, write canonical and idiomatic C++ that other C++ programmers will find to be good and maintainable C++.

    Sebastiani knows that the vast majority of C++ programmers will be put off by the code and so find it more difficult to maintain, yet has no intention of writing canonical and idiomatic C++.

    You see what I mean? The code Sebastiani offered is a very different beast.

    To be fair, I've lost more jobs than I've had precisely because I do not work well with others.

    I get what you're trying to do though, phantom. I feel like you're trying to push me. You're trying to actually help me become a professional programmer. Thank you. That means a lot to me.
    You seem like a good guy, and I hope you get a good job, but then I really don't really care if you get a job.

    More importantly, to me, you seem like you are willing to bash your head against the wall until you figure stuff out.

    I'm trying to push you along the path of a great C++ programmer.

    ^_^

    Of course, being a great C++ programmer will make you more employable so it all works out.

    [Edit]
    Actually, you know, it doesn't matter. Sebastiani is so much like Elysia in this regard it actually gives me a chuckle.
    [/Edit]

    [Edit]
    @laserlight: I admit; it is as much my fault as any, but now may be a good time to split this thread before the other two regulars show up and we get a repeat of the 100 post monster.
    [/Edit]

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  14. #29
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by laserlight View Post
    Certainly, but I note that you have not addressed the reasons given, and merely stuck to your proclamation that "exceptions make great control flow constructs" as if it were infallible dogma
    1) Exceptions are by definition and perforce flow-control constructs. The idea that they should only be used to signal errors is a convention. But really they are just a mechanism to ascend from the call stack in such a way that guarantees execution of certain blocks of code, and as such they have many uses above and beyond mere error propagation.
    2) How much affect they have on performance is a matter of debate and circumstance. Sometimes they lead to a speed up in code execution, in fact. Again, it just depends.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  15. #30
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    1) Exceptions are by definition and perforce flow-control constructs. The idea that they should only be used to signal errors is a convention. But really they are just a mechanism to ascend from the call stack in such a way that guarantees execution of certain blocks of code, and as such they have many uses above and beyond mere error propagation.
    I would argue that it is not just convention: it is by design. Furthermore, convention plays an important role in good design and readability. Granted, sometimes we might ignore the original design intentions and convention, allowing for arcane code in exchange for some benefit (template metaprogramming and Boost.Spirit comes to mind), but here constructs already exist to handle the logic efficiently in a conventional way. There is simply no benefit in abusing exceptions to perform normal flow control. Concerns about compiler bugs aside, your goto example would be a far better solution because that is a well known use for goto (even though it has its detractors allergic to all use of goto).

    Quote Originally Posted by Sebastiani
    2) How much affect they have on performance is a matter of debate and circumstance. Sometimes they lead to a speed up in code execution, in fact. Again, it just depends.
    I believe that the common cases where they lead up to a speed up in code execution is because the exception mechanism was not actually invoked. That fits the bill for error handling in that if there is no error, there is minimal cost, as opposed as to always having to explicitly check for the error at the call site. In normal flow control, on the other hand, the condition involved might always become true at some point, as in the case of getting out of a loop.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. goto statement help
    By lscamaro in forum C Programming
    Replies: 13
    Last Post: 10-24-2012, 11:47 PM
  2. Trouble using GOTO with the SWITCH statement!
    By xxJaRxx in forum C Programming
    Replies: 9
    Last Post: 03-10-2010, 06:42 AM
  3. GOTO statement in c++
    By kibestar in forum C++ Programming
    Replies: 8
    Last Post: 03-22-2009, 07:10 PM
  4. goto statement interpretation in VC 6 and 7
    By w262 in forum C++ Programming
    Replies: 2
    Last Post: 02-28-2005, 10:37 PM
  5. Goto statement
    By _JjC:: in forum C Programming
    Replies: 2
    Last Post: 03-02-2003, 10:43 AM