|
Yes, but injudicious use of low-level constructs such as goto will add complexity to the CFG.
I know every loop, if statement etc. is implemented using branches - but they are there explicitly to avoid needing to use those lower level constructs.
Is like the argument that assembler is more efficient. Except it usually isn't in the presence of modern architectural considerations such as caching and instruction pipelines. Modern compilers can target these architectures better, and higher-level constructs similarly give the compiler hints about the intent of code that are not available with the lower-level cases.
I will acknowledge there are places where it is useful, but I'd go with the advice that it should be avoided in 99.99% of cases, and even then only if you're fully aware of the repercussions.
In my experience, almost all of the uses of goto's can be replaced by higher-level constructs. There are exceptions, like the OCAML usage, but that's a fairly unusual case to be working on code like that. Many parser generators also generate code using goto's - that one is less arguable as there are frequently better alternatives.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
OriginalGriff wrote: If you know what you are doing, then you have enough experience to know when it
is appropriate to use. Yeah, but how do you know when you have enough experience to know when it's appropriate to use?
And then there's my sig...
If you think 'goto' is evil, try writing an Assembly program without JMP.
|
|
|
|
|
You mean you are 'grown up'! Can't believe that...
But as for the rest I agree with you - don't break rules just for breaking them...
I'm not questioning your powers of observation; I'm merely remarking upon the paradox of asking a masked man who he is (V).
|
|
|
|
|
Good grief no!
I'm just old.
The only instant messaging I do involves my middle finger.
English doesn't borrow from other languages.
English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.
|
|
|
|
|
After using FORTRAN for far too long (up to Fortran-77) with it's use of GOTO and, even more obfuscating, computed gotos, I started using C. However, I was self-taught and was therefore never was taught by anybody that there was a GOTO in the language! I used C for several years, then C++ and now I am firmly in the C# camp. I personally have never used GOTO in any of that code and was shocked one day to find a GOTO residing in someone else's code I had to fix. It was a revelation as big as finding out that one is allowed to use guns during a penalty kick-off. I didn't even know the syntax existed!
The whole point of my argument is that I never felt the need for a GOTO at any time, ever - so I didn't miss it. I didn't make artificial constructs to get around using GOTO; I didn't deliberately re-write my code to avoid using one; it just came about naturally that I didn't ever need one.
Having said that, I am sure that GOTO may be useful in some real-time code somewhere for performance reasons. My real bug-bear is with multiple RETURNs. I do actually go out of my way to avoid them and re-write them out of existence wherever I find them. I have not yet found any instance where multiple RETURNs from a method has been necessary. I miss allowing the drop through of CASE statements in a switch that has been removed in C#, forcing me to put BREAK at the end of each part and leading me to repeat code unnecessarily now and then so I am not always in favour of compiler/syntax restrictions in a language but I wish multiple RETURNs had been proscribed in the same way.
- I would love to change the world, but they won’t give me the source code.
|
|
|
|
|
I disagree to an extent with you about multiple returns: I'd rather see a method with validations at the top, each with it's own error report and a return than some "faffing about" code to avoid it.
I just think it makes the code look cleaner.
The only instant messaging I do involves my middle finger.
English doesn't borrow from other languages.
English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.
|
|
|
|
|
I always structure things to do validation at the top a bit like:
private bool SomeMethod(string someStingArg, int anIntArg)
{
bool workedOK = false;
if (IsValidForThisFunction(somString) && IsAlsoValid(anIntArg))
{
workedOK = true;
}
return workedOK;
}
...or, if individual validations are necessary...
private bool SomeMethod(string someStingArg, int anIntArg)
{
bool workedOK = false;
if (IsValidForThisFunction(somString))
{
if (IsAlsoValid(anIntArg))
{
workedOK = true;
}
}
return workedOK;
}
That way I still have only one exit - and I have all the validations at the top.
Obviously there are try...catch blocks involved but I wanted to put a simple layout.
- I would love to change the world, but they won’t give me the source code.
modified 10-Nov-13 18:52pm.
|
|
|
|
|
ERROR: Symbol "workedOK" is undefined in this context
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
|
I think that multiple return advice is not longer necessary in modern C++ - simply use RAII style techniques, and you are guaranteed correct cleanup at exit.
(Still shouldn't be overrused though)
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
OK, from a relative novice, here's the way I see it, and pardon me, but I come from a Qbasic/VB background.
As for multiple returns, if you have 10 conditions, lets say in a "Select case" statement, I see it OK to use multiple returns... if you have returns scattered, then I can see a problem.
I find the following a neat way of doing this... I'm usually not much for the ":", but again I find that on something simple like this, putting the condition and the return value on the same line improves readability
Select case i
case 1 : return false
case 2 : return true
case 3 : return false
end select
|
|
|
|
|
This serves as a single return as all gathered in one block
|
|
|
|
|
"Clever" use of GOTO can create macramé like code that is impossible to debug.
I may not last forever but the mess I leave behind certainly will.
|
|
|
|
|
Herbie Mountjoy wrote: "Clever" use of GOTO... Not only difficult to debug, it makes it difficult to alter. I ran into code that had an if goto, code, if not goto, unlabeled code. I didn't dare change it by removing the code that would never get executed. I didn't know why the code was there or what it was supposed to do or if I missed something "clever" done.
|
|
|
|
|
OriginalGriff wrote: it violates all the principles of good code design Actually "good" code design is an evolving thing. When I started coding, spaghetti code was normal and "good" I much prefer today's standard of "good" and look forward to new definitions of good. Just read an article about how we should eliminate IF statements. Interesting, but you can see how the "IF" was encapsulated in the routine executed. But that is part of the new "good", encapsulate and re-use existing logic.
|
|
|
|
|
It (goto) is unattractive certainly, and it's usage rightly deprecated. But for my money it's a mere misdemeanour compared to the worst sin in programming, namely global data.
There are developers who would rather eat their own limbs than use a goto, yet happily employ global variables with lavish abandon, supremely oblivious to the misery they are imposing on those who inherit their code.
I'm currently engaged in modifying a legacy VB6 app comprising around half a million lines of code. The many goto's therein are tiresome but just about tolerable. The multitude of global variables, all absolutely unnecessary, all toxic in the extreme, guarantee that an innocent change in one source file results in incomprehensible failures in a dozen others.
I'll happily deal with all the goto's a naive developer cares to throw at me, if they would just understand and apply the simple notions of encapsulation and data hiding. Not that I'm justifying the goto mind, but there are far, far worse offences.
|
|
|
|
|
I didn't even realise that C# had a goto statement!
Now that I do know this I will now use it in a profligate manner - mwahahahahah!
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|
|
Noooooooooo!
The only instant messaging I do involves my middle finger.
English doesn't borrow from other languages.
English follows other languages down dark alleys, knocks them over and goes through their pockets for loose grammar.
|
|
|
|
|
Nice, you can use it to replace all loop statements, but be careful!
|
|
|
|
|
You have just gained a level. Instead of blindly following some master wizard's rules, you now have begun to make your own. Before you know it you will zap your opponents with pointy pointers and even manage memory yourself.
I actually prefer working with people who occasionally contemplate to break the rules instead of reciting them.
Sent from my BatComputer via HAL 9000 and M5
|
|
|
|
|
Under the hood almost every code block that is put into curly brackets is implemented with machine instructions for conditional or unconditional branches. GOTOs, if you want. They have just been hidden away.
Unstructured spaghetti code is very hard to read and maintain. Readability and maintainability are even more important than correctness, at least in my book. Correctness will eventually follow as long as the code is readable.
What I don't like is when people start religiously following rules and can even recite the reasons for them, often obviously without understanding the intentions behind them. 'Bad' code may have some other advantage than readability. If that advantage in a specific situation becomes more valuable than readability, then I would happily do what needs to be done. I also would heavily comment it to document my reasons for doing this.
And the whole time I would enjoy the wailing of the code Nazis.
Sent from my BatComputer via HAL 9000 and M5
|
|
|
|
|
CDP1802 wrote: Under the hood almost every code block that is put into curly brackets is
implemented with machine instructions for conditional or unconditional branches.
GOTOs, if you want. They have just been hidden away.
I first cut my teeth on ICL System4 mainframes in 1979 and can still remember the conditional/unconditional branch instruction's machine code - 47 xx yy yy (I think JMP was it's assembler code mnemonic). XX was the condition, 0F was an unconditional branch. And YY YY was the prog address to go to. It's scary some of the completely useless info your brain retains.
If your neighbours don't listen to The Ramones, turn it up real loud so they can.
“We didn't have a positive song until we wrote 'Now I Wanna Sniff Some Glue!'” ― Dee Dee Ramone
"The Democrats want my guns and the Republicans want my porno mags and I ain't giving up either" - Joey Ramone
|
|
|
|
|
In the olden day (60's and 70's mostly), goto was abused as much as (or more than) var is today. Some programmers resisted this, lead by E. Dijkstra. They gathered momentum, lost their rationality, became zealous, succeeded in converting all new and most old programmers to their Holy Cause. As a result, The Hivemind took the position that all use of goto is nothing less than Pure Evil(tm), and now prefers to use highly obfuscated but structured control flow where a simple goto would have solved the problem in a simpler way. The Hivemind, ever hypocritical, also suggests refucktoring "nested loops where you exit both of them from the inner loop" to a confusingly-named and nonsensical-on-its-own function with multiple returns, a practice that it itself also denounces.
|
|
|
|
|
harold aptroot wrote: The Hivemind, ever hypocritical, also suggests refucktoring "nested loops where
you exit both of them from the inner loop" to a confusingly-named and
nonsensical-on-its-own function with multiple returns, a practice that it itself also denounces.
You mean the old story recursion vs. iteration? The stuff some eggheads traditionally use to torture students in their first semester?
Sent from my BatComputer via HAL 9000 and M5
|
|
|
|
|
That's fun too, but no - I mean the thing where they place the loops in a function and the goto turns into a return, and then they pretend that isn't really the same thing.
|
|
|
|