Empirical Study On How C Devs Use Goto In Practice Says "Not Harmful" 677
Edsger Dijkstra famously opined in 1968 on the danger of Goto statements. New submitter Mei Nagappan writes with a mellower view, nearly 50 years later: By qualitatively and quantitatively analyzing a statistically valid random sample from almost 2 million C files and 11K+ projects, we find that developers limit themselves to using goto appropriately in most cases, and not in an unrestricted manner like Dijkstra feared, thus suggesting that goto does not appear to be harmful in practice.
(Here's the preprint linked from above abstract.)
I prefer the Comefrom statement (Score:5, Funny)
It gives me so much more flexibility and power. The computed comfrom is even better.
Breakpoints (Score:3, Informative)
It turns out that many CPUs have hardware support for comefrom, usually to support debuggers. For instance, x86 has DR0, DR1, DR2, and DR3 [wikipedia.org]. And that's the only place I'd use a comefrom: as a debugging breakpoint.
And aspect-oriented programming (Score:3, Interesting)
Return from subroutine is the same as popping a function from the stack and tail calling it. "Comefrom" is a different construct, stating that whenever some other line of the program gets executed, a particular function will get called first. Have you heard of "aspect-oriented programming"?
why? (Score:5, Insightful)
Is that because they were warned by Djikstra that it would be harmful to use it haphazardly? Or is it for some other reason?
Re: (Score:3, Insightful)
Is that because they were warned by Djikstra that it would be harmful to use it haphazardly? Or is it for some other reason?
1. Because if you use goto in a class assignment, you lose points.
2. Goto is easy to avoid, and is a symptom of a poorly designed program.
3. Some compilers don't even try to optimize a function containing a goto.
I have occasionally used goto as a quick hack, usually to handle error conditions.
When I later go back and refactor the code, it is always cleaner and more readable without the goto.
Re:why? (Score:5, Interesting)
Really? You loose point for what is really the most sane way to handle cleanup in C? Have the instructors in those courses actually done any real work outside of academia? This is a very common pattern that I've seen in almost every large C code base that I've worked on.
static int
do_some_work (context_t context,
int x,
error_t **error)
{
int rv = 0;
database_t *db;
data_t v;
db = get_db (context, error);
do some work ...
v = compute_v (context, db, error);
if (!v)
goto out;
more work ...
out:
return rv;
}
It makes it so much cleaner and easier to read.
Re:why? (Score:5, Interesting)
Computer Science and Computer Programming are two different things. The academics are always on a quest for purity, people who work for a living want to get things done as cleanly and quickly as possible. Frequently the two minds align, but you won't convince the academic your goto is pure anymore than he can convince you to rewrite the code to remove it (which you could do).
Re: (Score:3)
Not all academics are against goto. Knuth is an academic, and he wrote on the structured uses of goto shortly after Dijkstra's edict. (Some of these uses have since been absorbed into constructs like "break" and "continue", but "break" can't break out of more than one loop at a time and "goto" can.)
I agree (Score:5, Insightful)
People forget that Djiksrtra wrote his famous missive back when the dominant languages were PL/1 and Fortran and goto was the main mechanism for flow control.
Dijkstra's point was perfectly sensible and a valid at the time. I'm just not sure that it deserves to be elevated to the status of Eleventh Commandment.
Re: (Score:3)
That is extremely unlikely.
At the end you reach a 'return' which is translated more or less to an assembly 'rts' statement which takes care of cleaning up the stack.
But perhaps you mean a goto that skips over function boarders? Not sure if you can do that in C and C++, if you can do that ofc. the stack is in your hands :) and you are at mercy of its limits.
Re: (Score:3)
So, bailing out leaves dangling threads, leaking memory, and deadlocks that show up the next time the function is entered.
It's the easy way out only once.
Re: (Score:3)
Every "goto out;" can be replaced by a "return rv;" which says explicitly what it does. The dislike of multiple return statements in a function is based on academic thinking, not reality.
Now, if you were doing more processing after "out:" than just a return statement, there'd be a case for what you're doing. Piling up end-of-function code like that is ugly, but there's often no way to do it better in C. In C++, you'd use RAII for resource management and not need any exit code.
Re: (Score:3)
The reasoning behind not having multiple return statements is the exact same reasoning behind not using goto, so you're basically solving nothing here.
Also, the example given is a poor one, it has only one place where an error can be generated (which is not the case you should address with goto, instead, the case where you have lots of steps, each of which could fail is), plus, it doesn't have any real cleanup work to do (e.g. it's entirely reasonable to expect that you may need to deallocate buffers you we
Re:why? (Score:5, Insightful)
If I worked for someone as rigidly blind as yourself, I'd have left years before you "fired me", "manager in your dreams".
THE ONLY RULE is that rules are meant to make you think carefully before you break them.
Rules are for the guidance of the wise and obedience by fools.
You, sir, are a fool.
Re: (Score:3)
I'd quit before then. Sheesh, evaluate the code on its merits instead of dogma.
Re:why? (Score:5, Insightful)
An improperly structured program, will behave however the compiler felt like making it behave when it turned your lines of gibberish posing as code into machine instructions that actually manipulate registers and memory spaces.
This misses an important point that (apparently) needs stating: complex and/or deep nesting makes code more difficult to understand by programmers (perhaps even the one that wrote the code in the first place). A simple goto-based assertion macro goes a long way toward linearizing the flow of code such that it is simple to understand. If the compiler has trouble with that, then the guy that wrote the compiler needs to try harder.
Re: why? (Score:5, Insightful)
What if I actually am an expert? Am I still bound by your superstitions about goto?
It's one thing to tell a student or beginner to avoid goto, but another thing to place an absolute prohibition on them.
The original goto-considered-harmful paper was written at a time when structured programming was extremely rare, spaghetti code was common, and the flowchart was a common design method. We're decades past that time though and the general programming style everywhere is to be highly structured. So the same repulsion about using goto is no longer necessary, we know enough to not use it at a whim but should be allowed to use it when it is indeed appropriate in languages which do not have the necessary structured constructs to avoid it.
Re: (Score:3)
You'd better post some better examples ASAP and back up your rationale, because you're empty assertions aren't winning over any new friends and your anecdotes don't seem to be very typical.
As it stands now, goto is a perfectly legitimate way of breaking out of loops and skipping to cleanup after an error, without the necessity of bringing in (n+1) nested `if` blocks, and unreadability and unmaintainability that comes with it.
Re:why? (Score:5, Interesting)
While I agree that certain constructs, like "goto" should not be used, I will point out that the full title of the 2004 version of the MISRA C document is:
MISRA C:2004 Guidelines for the use of the C language in critical systems
Note the word "Guidelines".
Also note section 4.3.2, which discusses deviation procedures. In summary, it recognizes that full compliance is not always practical. And when deviations are made, they must be documented, justified and reviewed. Sometimes, such reviews involve showing 2 versions of the code in question: One without the deviation and the other with, so that the relative risks can be analyzed and discussed. Sometimes this process can result in an alternative with either a "less serious" deviation or no deviation. And sometimes the deviations are approved as-is.
At the consulting company I work for, how strictly the various guidelines (not just MISRA, as only a few of our clients are automotive) deviations are approved depend on the customer. We certainly make great effort to only deviate from the various guidelines when the risks of compliance outweigh the risks of non-compliance. Sometimes business considerations override engineering considerations.
Re:why? (Score:4, Interesting)
And how would you write acquireResources?
Re:why? (Score:5, Insightful)
How many levels of nested if blocks are you willing to tolerate solely in the name of avoiding a single use of the keyword goto?
Re:why? (Score:4, Interesting)
If GOTO would actually alleviate that problem for you - You've already done something very, very wrong.
I have written a lot of code in my life - Thousands of projects, millions of lines of code (for whatever that means), across a dozen languages and twice as many platforms. And outside Assembly (and DOS batch, if you want to count that as a "language"), I have not ever encountered a situation where I thought to myself "gee, I could really improve this with a GOTO, if only everyone wouldn't laugh at me for it".
I have, however, removed some pretty heinous uses of GOTO from other people's code. The most common one I see, people can't quite bring themselves to "return" from an error handler in the middle of a function, so they instead GOTO the end of it. Really??? Talk about missing the forest for the trees!
I don't think I would so much call GOTO "harmful", so much as "completely unnecessary in any modern language".
Re:why? (Score:5, Insightful)
Re: (Score:3)
The most common one I see, people can't quite bring themselves to "return" from an error handler in the middle of a function, so they instead GOTO the end of it.
I'd bet this is because of another slavishly followed idiom, which is that it's considered a bad practice to return early from functions. I'd guess that argument gets made because it's easy to miss the fact that the function is returning early, and thus accidentally leak a resource that was allocated earlier. While this is a good principle in general, it's always important to understand there are good exceptions for most any rules or idioms.
Generally speaking, I tend to use early returns exclusively for e
Re:why? (Score:5, Insightful)
The problem is that the above is a remarkably simple case. The reality for a lot of cases where goto gets used for error handling is that with the above what you would end up writing is:
bool success = doSomethingThatMightFail(); ...
if (success) {
success = doSomethingElseThatMightFail();
if (success) {
success = doMoreFailingStuff();
if (success) {
success = yepMoreFailingStuff();
if (success) {
}
}
}
}
if (!success) {
cleanupWork
}
Meanwhile with a reasonably constructed macro to wrap his pattern, you end up with:
bool success = true;
CHK(doSomethingThatMightFail());
CHK(doSomethingElseThatMightfail());
CHK(doMoreFailingStuff());
CHK(yepMoreFailingStuff());
end:
if (!success) {
cleanupWork
}
That's much easier to read, and just as safe.
Don't get me wrong, in a language where you can use exceptions for this, or better yet, the error monad, you should absolutely use those more abstracted concepts, but in plain C, this really is the best approach to handling errors in code where everything you do could go wrong.
Re: why? (Score:4, Informative)
Your post implies you don't know how the C && operator works...
To simulate exception handling (Score:3)
Goto is easy to avoid, and is a symptom of a poorly designed program.
[...]
I have occasionally used goto as a quick hack, usually to handle error conditions.
In languages with exceptions, one uses a finally clause (or a C++11 scope guard) to perform cleanup, such as releasing memory or non-memory resources that a function owns. In C, one uses goto to jump to the cleanup code if it detects an exceptional condition. Or is a program that needs to do this sort of cleanup "poorly designed" solely on account of being implemented in C instead of a language with language-level exceptions?
When I later go back and refactor the code, it is always cleaner and more readable without the goto.
By "refactor" do you mean "rewrite in C++"? If not, could you give an example of su
goto for coroutines (Score:2)
Because if you use goto in a class assignment, you lose points.
If the assignment is "Implement a coroutine mechanism for C", why would a sane instructor dock the student for making something like this clear wrapper around goto [greenend.org.uk]?
Re:why? (Score:5, Informative)
Not to mention all conditional statements and loops are just a subset of goto. Try writing some ASM.
Re:why? (Score:5, Insightful)
There may be a better pattern, but in a few cases ...
Like many (most?) tools, the GOTO can be used and abused. Only pendants are convinced the issue is black and white.
Re:why? (Score:5, Insightful)
1 and 3 are certainly true. 2 is not always. For example, if an error condition requires unwinding such as releasing resources. Compared to deeply nested ifs and having to essentially duplicate the entire control flow in the bottom half of the function, gotos can make things much more readable and even improve performance.
Perhaps a better statement is that goto will be found in code that is either very well designed or very poorly.
Re:why? (Score:5, Interesting)
Is that because they were warned by Djikstra that it would be harmful to use it haphazardly?
Programmers are more used to structuring their code (using functions, modules, etc.) and using best practices (minimizing globals, separation of concerns, etc.). This was not so much the case in the late 60's. That, combined with the "goto stigma", means that average developers avoid goto usage and good developers know when it's worth it.
We saw a similar backlash with the concept of operator overloading. People abused it in C++, the Java designers overreacted and prohibited it, but most languages since then recognize that "yeah, operator overloading's really nice when you're building an API for mathematical constructs" (like complex numbers, quaternions, and matrices). So it's there in C#, Python, D, Rust, Scala, but (from the little I've seen) people seldom abuse it these days.
Re: (Score:2)
"yeah, operator overloading's really nice when you're building an API for mathematical constructs" (like complex numbers, quaternions, and matrices). So it's there in C#, Python, D, Rust, Scala, but (from the little I've seen) people seldom abuse it these days.
Why is it there, then? If operator overloading is only useful for mathematical constructions, why not simply bake those things into the language and be done with it rather than provide operator overloading which can, amongst other things, also be used to build those libraries?
After all, those are libraries. They can easily be provided as part of the language with no impact to the actual language or the language usage... if that is all that overloaded operators are used for! Unfortunately the truth is that o
Re:why? (Score:4, Insightful)
Because there are an infinite number of possible mathematical constructions. You can't bake them all into the language; you need to provide facilities for the programmer to write his own.
Re: (Score:3)
Yes, he should when he needs it.
Why should a programmer use different notations as a methematician would?
Why should I be forced to read the doku of a rarely used math library to figure out what stupid abreviated function names the coder used, instead of using + and - as used in the MathML snapshot in my Word Document the companies chief mathematitian gave me as specc?
Sorry, human beings invented mathematical notations. Other human beings invented programming. Most human beings proficient in both, want to us
Re: (Score:3)
I think that's likely. It became such a taboo that developers tend to think it over thoroughly before actually using it.
Re: (Score:2)
I was wondering that too, but, there is another one.... what if the real issue was simply Djikstra's underestimation of how obvious the pitfalls with goto are.
Its easy to accidentally cut yourself with a knife, its also easy to see the danger and most people learn to use one without cutting themselves pretty quickly. The pitfalls are easy to see, and making mistakes causes pain.... much like Goto.
The problems with it are easy to see if you just use it a few times. I learned to use goto in applesoft basic,
Re:why? (Score:4, Insightful)
I was wondering that too, but, there is another one.... what if the real issue was simply Djikstra's underestimation of how obvious the pitfalls with goto are.
1968 was the year Djikstra wrote his article. At that time, arguably the dominant languages (FORTRAN IV and maybe BASIC) did not have structured control-flow constructs such as if-then-else, do-while and begin-end blocks. Others that contained these constructs (PL-I and Algol come to mind) were struggling for mind-share.
Without structured control-flow constructs, one is pretty much forced to write goto statements everywhere. I think Djikstra's cautioning against the use of gotos was also a call to abandon them in favor of the structured approaches that the new languages supported. And he was right: if you're using gotos to replace structured control-flow, then you're abusing gotos.
You shoulda seen programs before Djikstra! (Score:5, Informative)
In the 60's and much of the 70's, most people wrote in high-level languages as if they were coding assembler. Goto's all over the place. Not that they had a choice -- for example, control flow in Fortran IV, the most-used high-level language of the time, featured IF, DO (a crude version of the modern FOR -- not do), GOTO, CALL, RETURN. No else, while, do/while, no modern-style for, case, etc. AND, get this: NO BLOCKS; the IF statement controlled only a *single* statement, so that meant you often *had* to say IF (...) GOTO xxx. Just like assembler. It was awful! There were other less-popular but more-evolved languages, but unstructured practices were very often carried over to those as well. GOTOs were just how most programmers thought.
That's the backdrop for Djikstra's condemnation of GOTO. Certainly, the then-current mass use of GOTOs was a very bad thing since it completely obscured program logic. If you read the original article, he's not so much condemning GOTO as he's arguing for structured programming.
Consider GOTO Considered Harmful as a successful wake-up call. By keeping his message black/white, i.e. GOTO is bad, he gave his message punch and made it much talked-about. People started to think in a more structured manner (though at first we thought the "structured crowd" were a bunch of weenies), and started to demand better control-flow features. Pretty soon, structured control-flow was de rigeur in any new or revised language. Fortran even got IF/END IF in Fortran 77!
People nowadays have hardened the anti-GOTO bias into gospel. At the time, the response was more nuanced, more in line with the spirit of what Djikstra was saying. For example, in 1974 even Niklaus Wirth's new PASCAL (a principled, hard-line structured language if there ever was one) included the goto statement with the warning in the User Manual and Report that "the goto statement should be reserved for unusual or uncommon situations where the natural structure of an algorithm has to be broken." If anybody was going to out-and-out outlaw goto, Wirth would have been the guy.
XKCD (Score:4, Funny)
How much unsafe use has Dijkstra prevented? (Score:4, Insightful)
Goto is being used safely (relatively) now, but would have the programming practices that cause that to be true become so prevalent without his warning that it had potential for problems?
Re:How much unsafe use has Dijkstra prevented? (Score:5, Interesting)
As someone who saw the programming practices of the 1960s and early 1970s, I can assure you that Dijkstra's warning was needed.
It caused a massive change in practices among software professionals, within a few years GOTO had almost disappeared from most new code.
I remember seeing code from a "sales engineer" in 1975 that was so full of buggy gotos that we refused to even attempt to debug it.
He learned.
Re: (Score:2)
Yes, because people would have run into those problems and someone else would have made the same warnings.
He probably saved someone a lot of grief way back when, though.
What's the term for a prophylactic prediction? (Score:5, Insightful)
There is an implication that Dijkstra was wrong about the goto - the implication being based on how conservatively it is used.
Perhaps it is wiser to conclude that the goto is used so conservatively because Dijkstra was right and that programmers have, in general, taken his wisdom to heart and avoided the goto except for those instances where, properly documented, it is the best tool for the job.
(By prophylactic prediction I mean the sort of warning or planning that completely forestalls the danger predicted, through awareness, preparation, etc. Kind of like the Y2K non-event.)
Re: (Score:2)
I agree, but i can only think of one instance that gotos are appropriate and that is cleanup. I think this is basically because C does not have any nice way to handle cleanup, a finally block would get rid of most valid uses of goto.
Re: (Score:2)
Problem is, a finally block effectively changes the meaning of code within it by tagging any return statements with extra code. A line being changed by another line far away seems far more inelegant and prone to confusion than goto.
Re: (Score:3)
Indeed. And if one is old enough to have read/maintained any FORTRAN code dating from Dijkstra's era, you can understand why he wrote this paper. A lesser being would have gone off on an apoplectic rant. In fact, I may be one of those lesser beings, myself.
Re: (Score:2)
It reminds me of a joke. It was something like :
* What do you do for a living?
* I protect the population : I'm a velociraptor hunter
* But, there's no velociraptor!
* You're welcome.
Re: (Score:2)
If you have a formal education you have heard of his name for A*.
If you don't you will at the very least have heard the sentence Goto Considered Harmful ... and I think we can all agree it's a snappy turn of phrase, hard to forget and by now iconic. Unless you lock someone up in a cave with The C Programming Language before they learned any programming I think they'll have heard of it by the time they are proficient with C.
Re: (Score:3)
to prove that a program is type-safe.
Which usually is, as it has almost always been, the least of one's worries.
goto fail (Score:5, Informative)
https://www.imperialviolet.org/2014/02/22/applebug.html
Well, yeah (Score:4, Informative)
Because we all got the warning, and thus did not write horrible goto-festooned spaghetti code and only use goto when appropriate. This means Dijkstra's letter was a success. Also, it was Niklaus Wirth who decided to use the "considered harmful" verbiage, not Dijkstra.
Re: (Score:3)
Re: (Score:3)
Now, we write horrible, impossible-to-follow, spaghetti code without goto!
Remember kids, 'spaghetti code' refers to code with complex *control flow*. That is, if you trace it with a pencil, you end up with a document that looks like a plate of spaghetti. We're, arguably, worse-off now than we were before goto became taboo.
We learned the wrong lesson.
In smalltalk, everything happens somewhere else. --Adele Goldberg
all languages can be abused (Score:2, Insightful)
All languages can be abused.
goto is no different than if nests or giant nested for loops or any other maddening crap people can come up with. If you look at the code most C compilers come up with they are not afraid of a goto...
Goto used correctly is a good tool. Its just a tool. Do not treat it as something bad or good. Look to how it is used.
Re: (Score:2)
If you look at the code most C compilers come up with they are not afraid of a goto
As if they had a choice!
To be expected (Score:3)
This makes sense for a couple reasons.
First, abusing goto really serves noone. It doesn't make code quicker to write. It certainly doesn't make it easier to understand. There is no benefit to it.
Second, I'd argue that very few people want to write new code in C these days. Those who do have specific reasons for it and are probably a bit more experienced or passionate and thus aren't the kinds of people who'd readily abuse things. The ones who would are going to be mostly attracted to easier high-level languages that don't allow the abuse in the first place.
Re: (Score:2)
Goto these days is a stenography tool... it's designed to make the code harder to read.
Re: (Score:2)
Lots of 'Internet of Things' code will be written in C (with some ASM and C++) as the 'things' tend to be resource constrained. That's a big market coming up.
I'm enjoying using C again on devices with similar performance to those I was using 30 years ago (now: ATMega328P running with 1MHz CPU, ie 1 MIPS; then Z80A with 4MHz clock making for ~1MIPS) but with lots better development tools this time, and several GHz of laptop to run them on.
https://sourceforge.net/p/open... [sourceforge.net]
When not writing C (and developing h
Re: (Score:2)
Lots of Internet of Things stuff runs on ARM Cortex M3/M4 on > 100 MHz CPUs. Plenty of resources for lazy development.
Comment removed (Score:3)
Re: (Score:3)
Error handling with multiple instances of allocation.
Eg, something like:
char *buf1 = malloc(...);
if (!buf1) goto abort1;
char *buf2 = malloc(...);
if (!buf1) goto abort2;
char *buf3 = malloc(...);
if (!buf1) goto abort3;
return;
abort3:
free(buf2);
abort2:
free(buf1);
abort1:
return;
Also, bailing out of multiple nested loops.
Re: (Score:2)
...and of course I messed up, that should be:
if (!buf2) goto abort2;
if (!buf3) goto abort3;
The ability to edit comments would be nice.
Re: (Score:3)
I was forced to take the introduction to programming class in college because the Turbo Pascal program I had used a goto for this very reason. In Pascal there was no break/continue equivalent and it would have been extremely messy in the code to not use the goto.
It later turned out that the professor did not know Pascal at all when there were simple errors in a 2 page program that she couldn't get to compile. I only showed up for the midterms and final for that useless class. The next one was worse since th
Limited sample :) (Score:4, Funny)
I bet the "valid random sample" didn't include any projects from the Obfuscated C Code Contest [ioccc.org].
That's because of "Goto Considered Harmful" (Score:2)
That result's because programmers got the ideas in "Goto Considered Harmful" pounded through their skulls while they were learning, and handled it like they would dynamite: it's very effective and the best tool for certain jobs, but it's also very dangerous and capable of causing a ton of damage so you should handle it with an abundance of caution. tl;dr: "Use it to crack huge boulders and tree-stumps, not to loosen bolts."
Outdated... (Score:2)
"GOTO" existed before subroutines and functions were added, and it was back in the days of line numbers. This was the point where the main menu part of a program had to jump over to the appropriate part of the program, now we just call the appropriate routine.
Re: (Score:2)
"GOTO" existed before subroutines and functions were added, and it was back in the days of line numbers. This was the point where the main menu part of a program had to jump over to the appropriate part of the program, now we just call the appropriate routine.
But more than that, GOTO is how processors work at the lowest level. All of those fancy blocks in a modern language get turned into "jumps" and such at the lowest levels when compiled. The first computer languages - such as fortran - were a pretty thin veneer over assembly, anyway, so gotos made sense.
Way to bury the lead (Score:5, Insightful)
Re: (Score:2)
Bingo: you win tonight's Internets...
Rgds
Damon
PS. Like all that Y2K work I wasn't doing in a bank that wasn't necessary except that it was...
Re: (Score:2)
So true, but out of mod points :D :)
And yes... I read at -1 too
Still Harmful (Score:2)
Blocks considered harmless (Score:3)
It's no surprise that goto's are used sparingly - and generally only with very good reason - by modern programmers. Dijkstra's paper is dated 1968, which is about the time ALGOL was invented. ALGOL which was the first block-oriented language. Heck, maybe its design was even influenced by Dijkstra's paper - who knows?
Given a language that supports blocks (and all modern languages do), there's little reason to use gotos. Instead, you use blocks and related goto-like constructs such as break, return, try/catch, etc. Anything but a literal goto.
IIRC, the CPython source code has a few goto's in it. I remember that Tim Peters once defended that as being the best solution (in C, at least) for certain very exceptional situations. It's no coincidence that they're used very, very sparingly there. And maybe they wouldn't be needed at all in CPython if C had a try/catch construct - like Python itself.
In my own case, I've used them mostly when transliterating some ancient FORTRAN code into C. Rather than untangling the code into blocks, it was simply easier to replicate the goto's. At the time, I actually had to consult K&R to brush up on C's goto syntax. Also, the FORTRAN code I was working with was proven and needed little maintenance, so removing the goto's was more likely to make it worse than to make it better.
Re: (Score:2)
Correction: I see now on Wikipedia's ALGOL page [wikipedia.org] that blocks were introduced in ALGOL in 1960. So maybe ALGOL influenced Dijkstra rather than the other way around.
No one is using GOTO because .... (Score:2)
Really this is a COMEFROM statement, no?
bool OnRightButtonClickCallBack(void *a, void *b, void *c){
int xx=int(a);
int yy=int(b);
global_window *gw=(global_window *) c;
}
longjmp() (Score:5, Funny)
is far more entertaining than a mere goto.
Re:GOTO is a crutch for bad programmers (Score:5, Informative)
void func() {
if (!AquireResource1()) goto end;
if (!AquireResource2()) goto cleanup1;
if (!AquireResource3()) goto cleanup2:
DoStuffWithResources();
Cleanup3();
cleanup2:
Cleanup2();
cleanup1:
Cleanup1();
end:
return;
}
Re: (Score:2, Funny)
Some sort of nested do { ... } while(false); and break; would be my first suggestion.
Rgds
Damon
Re:GOTO is a crutch for bad programmers (Score:4, Informative)
Fundamentally, that *is* a GOTO. It's just a less-readable idiomatic GOTO that doesn't include the "goto" keyword.
Re: (Score:3)
The key virtue, such as it is, of the do { ... } while(false), better wrapped up in a macro, is that it makes it harder to get the nesting wrong by accident, which is critical.
With goto there is no such safety net.
But I think we're agreeing furiously.
Rgds
Damon
Re:GOTO is a crutch for bad programmers (Score:4, Insightful)
So abuse loops and nesting when you have no intention of looping? And use break which is just goto lite?
That always seems like standing on one's head to please the compiler.
Re: (Score:3, Insightful)
This is simpler, cleaner, and avoids the goto:
void func() {
if (AquireResource1()) {
if (AquireResource2()) {
if (AquireResource3()) {
DoStuffWithResources();
CleanUp3();
}
CleanUp2();
}
CleanUp1();
}
ret
Re: (Score:2)
It's even worse, but it avoids the word "goto" (while still being a goto IMHO):
while(1) {
if (!AquireResource1()) break;
DoStuffWithResources();
break;
}
Cleanup();
Re: (Score:2, Interesting)
void func() {
if (AquireResource1()){
if (!AquireResource2()){
if (!AquireResource3()){
DoStuffWithResources();
Cleanup3();
}
Cleanup2();
}
Cleanup1();
}
return;
}
Re: (Score:3, Interesting)
I find the gotos easier to read than the nested set of if statements. Especially because the gotos are a well known idiom for handling this type of error/cleanup.
Re: (Score:2)
Re: (Score:2)
What would you propose as a better alternative to this idiom in a language that lacks exceptions:
I propose this [stackoverflow.com]; namely using variables to keep track of the state of resources, and then cleaning up based on the values of those variables. In my experience this is much less error-prone than the "goto" equivalent - for example, reordering the code is much less likely to break the cleanup.
Re: (Score:2)
void func()
{
if (AquireResource1())
{
if (AquireResource2())
{
if (AquireResource3())
{
Re: (Score:3)
I've seen 3 or 4 attempts to make the nested logic correct and/or readable. The statement with the goto's was easy to understand. Immediately. I think it proves the point that sometimes goto's have a place, and actually may be a better solution.
Re: (Score:3)
If AcquireResource1() fails, you have unitialized entries in resources[1] and resources[2].
And this array only works if your resources all look the same.
Re: (Score:2)
if (AquireResource1()) {
if (AquireResource2()) {
if (AquireResource3()) {
DoStuffWithResources();
Cleanup3();
}
Cleanup2();
}
Cleanup1();
}
return;
}
Isn't this a textbook example of unwounding a stack?
Re: (Score:2)
C++ on an MCU? (Score:2)
Okay, then I'd recommend C++.
So long as your target machine is big enough to support C++'s support library. People used to joke about "Think of the elevator controllers!" [jargon.net] as an excuse people give to hold up language design. But it's no joke anymore, as Arduino's MCU kits brought programming for a constrained machine to the masses.
This is C, not C++ (Score:2)
"Cleanup resources using destructors"
Good luck with that.
Re: (Score:2)
Re: (Score:2)
Comment.c:12: Warning missing return before }
Re: (Score:3)
That's horrible with the code duplication. It gets even worse if the cleanup is 2 or 3 lines per resource.
Both kinds of ALTER are still in use (Score:2)
What kind of ALTER statement are you imagining?
Re: (Score:2)
Re: (Score:3)
What I would have loved to see in C would be a different keyword for break for exiting a loop versus ending a switch case. 90% of the times in recent years that I've been tempted to use goto have been when I've written a switch statement in a loop, and need to break out of the loop from one of the cases. I have to steel myself and either rewrite the particular case as an if statement before the switch (nasty), or fiddle around with flags to break out of the loop after the switch statement, or check it as pa