//...
label_000:
//Somewhat complex stuff here.
if (/*...*/){
if (/*...*/){
//...
goto label_000;
}
//...
}
//...
I don't see what is complicated about making that code into a simple loop. It looks similar to how someone would write a do..while loop in assembly code where you only have jump and compare instructions. You simply jump back to the label if the if statement evaluates to true. In C++, the continue statement would jump back and reevaluate the condition. What's the big deal about that line of code?
//...
while (1){
//Somewhat complex stuff here.
if (/*...*/){
if (/*...*/){
//...
continue;
}
//...
}
break;
}
//...
I could have written it like that, but I have aversion to loops that are actually gotos in disguise. If I have to choose, I'll choose the literal goto. At least it's not trying to hide what it is.
Don't get me wrong. I have nothing against while (1){}, it's loops like the one above, with their unconditional breaks at the end, I don't like.
How did you write Assembly without jumping? I mean, I could understand not using jmp, but what about the conditional jumps?
How did you write Assembly without jumping? I mean, I could understand not using jmp, but what about the conditional jumps?
I didn't. Obviously there is no while or if statement in assembly (at least not in any languages that I have seen). However, the way we did it was still structured like a conceptual do.. while or while. We would have flowcharts showing a while loop. We weren't allowed to jump straight out of a loop to some other label, however. We were required by our coding standards to follow the flow charts perfectly. We were also disallowed from jumping into the middle of an if..else, or while loop. We had various flavors of jumping statements that could be used to implement a do..while or a while.
I guess we will have to respectfully disagree on the concept of the "hidden goto". I do not see a while loop and continue statement has a hidden goto. Although the assembly may be the same, the idea of HOL programming is to write code that is easier to read and maintain and so we have these tools such as while, do..while, if..else, switch, try..catch and so forth. Yeah, you could do all of your looping with if statements and goto statements but it would look a lot like the jump instructions used in assembly which in my mind defeats the purpose of having the tools provided by the HOL. That's just my 2 cents.
I think you misunderstood what I said.
I'm not saying that all flow structures are gotos and can be manually built with them. We all know that's true, so there's no point in saying it.
I oppose that particular shape of loop because it's a misuse. A loop is meant to do something a number of times, or while a condition is met. That's how loops were meant to be used, and that's where they the most comfortable.
That loop doesn't follow that pattern. It will often run just once. Unless a condition is met, in which case it will go back to the beginning. If someone came and began reading the code, they would have to fully understand the structure of the loop before they could figure out its purpose and how it will behave (assuming there were no comments, of course), because the loop is different from the traditional "run while this is met". On the other hand, if someone sees a label, they'll just think "okay, so there a goto around here, somewhere". The very fact that goto is so rarely used (on well-written code, that is) keeps the reader on their toes and makes them pay more attention. If you just see a while, you're not going to think "is this a regular while, or a special while?".
This is why I think it's silly to ban goto. I obviously agree that there are many cases where it would be misused; but while it is true that most of the cases where it wouldn't be it can be replaced by a loop or something else, that doesn't necessarily make it the best choice.
Just because it's structured, it doesn't make it better.
Of course you can go years without ever using it, but to my ears that's like saying "I've been programming for ten years and I've never used a single switch!" This is programming, not a handicap race.
I think goto is useful. I use it sparingly, though.
Just only use it when it really is the best option. If, for example, you've got a condition; and if the condition is met you want to jump straight to the beginning of the function; why write a giant loop that encompasses 60 lines when you can write a goto? It's just simpler in some cases.
What, when it's the most sensical option is the worst time to use it? Surely the worst scenario to use it in is one where a while or for loop is better.
Looking back, my example was terrible.
I rarely use them anyway. Maybe if you're checking input against a regexp.
Code has to be clear on what is intended rather than just being syntactically correct. Most C++ developers would find the originally posted code surprising (even alarming), perhaps a little less surprising for a C developer.
If you received a call at 3am to fix some program that just crashed in a live environment, could you, at a glance, be comfortable that that loop was ok and could your confidence in the code's quality remain high? The answer is no because if someone was capable of putting that construct in production code, who knows what else they might do.
It is helpful to draw an analogy between functional and structured programming.
In the past, the characteristics and advantages of structured programming have
been summed up more or less as follows. Structured programs contain no goto
statements. Blocks in a structured program do not have multiple entries or exits.
Structured programs are more tractable mathematically than their unstructured
counterparts. These “advantages” of structured programming are very similar in
spirit to the “advantages” of functional programming we discussed earlier. They
are essentially negative statements, and have led to much fruitless argument
about “essential gotos” and so on.
With the benefit of hindsight, it is clear that these properties of structured
programs, although helpful, do not go to the heart of the matter. The most important
difference between structured and unstructured programs is that structured
programs are designed in a modular way. Modular design brings with
it great productivity improvements. First of all, small modules can be coded
quickly and easily. Secondly, general purpose modules can be re-used, leading to
faster development of subsequent programs. Thirdly, the modules of a program
can be tested independently, helping to reduce the time spent debugging.
The absence of gotos, and so on, has very little to do with this. It helps with
“programming in the small”, whereas modular design helps with “programming
in the large”. Thus one can enjoy the benefits of structured programming in
FORTRAN or assembly language, even if it is a little more work.