Empirical Study On How C Devs Use Goto In Practice Says "Not Harmful"
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.)
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.
-1, Too Many Layers Of Abstraction
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.
void func() {
if (AquireResource1()){
if (!AquireResource2()){
if (!AquireResource3()){
DoStuffWithResources();
Cleanup3();
}
Cleanup2();
}
Cleanup1();
}
return;
}
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.
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.
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).
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"?
It's crap because he's regurgitating what he learned in programming class, from a professor who repeated the mantra "goto bad". Consider the quote from Knuth.
"Please don't fall into the trap of believing that I am terribly dogmatical about [the goto statement]. I have the uncomfortable feeling that others are making a religion out of it, as if the conceptual problems of programming could be solved by a single trick, by a simple form of coding discipline!." -Knuth
That being said, I demand a flow chart included in the documentation when goto is used for anything other then error handling. Those who demand to use the goto are willing to write the flowchart.
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?
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".
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.
Don't try to out wierd me, three-eyes. I get stranger things than you, free with my breakfast cereal. --Zaphod Beeblebr
And how would you write acquireResources?
Don't try to out wierd me, three-eyes. I get stranger things than you, free with my breakfast cereal. --Zaphod Beeblebr