Here's one refactoring for the situation you describe, that results in more even benefits than just removing the gotos/returns:
By adding extra useless variables, as I originally pointed out. And introducing a sea of "&&"s. I guess at least it looks more like a bowl of pretzels than a dish of spaghetti.
Whilst they result in execution stopping at a line in the middle of a block, they do so using an explicit built into the language block structure, that defines exactly which section of code may do so.
In a language like C++, unless there's a "try" block within the function, they are exactly the same as a "return" as far as that function is concerned, and can be invoked from the same places. I don't see why you think that that's acceptable if return isn't.
If you look at the FAQs for the Go language, the designers explain why they think exceptions suck in general, and why they largely replaced them with multiple return values. So not everyone shares your enthusiasm for exceptions, which are really just a kind of "return" statement on steroids.
On the internet, there are trolls...
"This is not a scientific study."
Then explain the lack of similar quantities of malware for iOS between 2007 and 2012?
It's for the same reason that the murder rate inside Disney World is very low.
1. "nested brackets" (blocks) are by definition not spaghetti.
I called it spaghetti because the resulting mass of brackets looks just like a big steaming dish of spaghetti, and the extraneous control statements are almost as annoying as gotos to more than a single "error" label.
Nested blocks are refactorable into smaller functions. That's the way to cut them down to size, not to use gotos.
Some are, some not so much. Many situations call for a long list of sequential checks, which can be cleanly and clearly coded as a bunch of if
- If you do it the obvious way, you still need a deeply nested if-then chain. You haven't solved the problem.
- If you put each check within a function and daisy-chain them, you get creepy action-at-a-distance. It's not clear to the reader that you made a whole bunch of functions that should only be called from one place, and that they must be daisy chained.
I mean really! People still trying to argue with structured code in 2014! You'd think it was still the 1980s.
You seem hung up on definitions. If you narrowly define structured code as code that lacks return, break, continue and exception statements (which can all be used to break out of your "structured" sandbox), then plenty of people would argue with it in 2014.
The main problem with early exits is using them in C. But C is such an unsafe language in general, that's really the least of your worries. Other languages provide nice features like automatic destructors and "with" statements that make early exits perfectly reasonable.
Yeah, force people to write a big pile of nested bracket spaghetti and manually back their way out of every case. Make them introduce a bunch of otherwise useless flag variables and extra conditional statements to keep track of it all.
The best part of it all: When all that extra obfuscation causes bugs, it would be harder to pin the root cause on a simplistic generalization like "goto === bad".