[Cryptography] The GOTO Squirrel! [was GOTO Considered Harmful]

Sampo Syreeni decoy at iki.fi
Mon Mar 3 20:07:58 EST 2014


On 2014-03-02, Theodore Ts'o wrote:

>> Au contraire!  You've fallen to exactly the same trap that you accuse 
>> others.  You see that we are all focussed on cause A: bad code, and 
>> we are missing cause B: lack of process.  By saying it is all about 
>> B, you are missing that A is a contributor.
>
> You're begging the question about whether the "goto cleanup handler"
> coding style is a bad coding style.  Yes, it was present for this
> particular failure, but so was the fact that the author was right (or
> left) handed.  Does that mean being right handed was a contributor?

Yes. First, thinking like this is a naked cum hoc ergo propter hoc. What 
probably happened here was a copy-paste mistake. Counterfactually 
speaking, could it then have happened otherwise, without gotos being 
involved in any way? As easily? I think it could have.

Take for instance Java's structured exception facility. Someone might 
well be tempted to write code like:

try {<something> if (error) throw Exception;} catch (Exception) 
{<whatever>}.

Using that syntax you're not likely to make the same precise error, 
because it'd lead to something unsyntactical like and you can't just 
copy-paste it in:

try {<something> if (error) throw Exception;} throw Exception; catch 
(Exception) 
{<whatever>}.

However, if you're drowsy enough to make the first mistake and not 
notice it once you made it, you're also well eligible to commit e.g. the 
following one from sheer muscle memory and copy-paste habit:

try {<something> if (!!complicatedErrorCheckingMethodName) throw 
Exception;} catch (Exception) {<whatever>}.

The effect is essentially the same, the source of it is essentially the 
same, and clearly it has nothing to do with gotos at all.

So my point is, while you probably can guard against certain errors via 
syntactic means like forbidding gotos, you really, *really* can't guard 
against all of them, and even if your failure model is a 
bored-to-silliness coder repeating something via a careless paste 
operation, you're in general probably out of luck.

Second, as for gotos per se, I believe they're a misunderstood beast. 
Most who rail against them never read or at least understood Dijkstra's 
original demurral. His point wasn't that goto's are bad per se. It was 
that they invite the kind of undisciplined coding style and muddled, ad 
hoc thinking style about algorithms which leads to spaghetti, and soon 
thereafter to code you can't (provably) formally analyse or verify.

So, gotos don't automatically lead to trouble, nor are they evil an 
sich. With proper, slavishly elegant, high coding style they can 
actually serve you pretty well on occasion. It's just that they make it 
so very easy to hose yourself, and as such, it'd be better to leave them 
out of language syntax.

In this case, there was nothing wrong with the coding style per se. What 
probably happened was an inadvertent double paste which wasn't caught in 
time. As I argued above, that's not a problem which is intrinsically 
tied to gotos, and quite probably (absent some work in formal grammars 
I'm not aware of) something not something you can fully and/or usefully 
control via syntactic means. Instead it seems like a problem for quality 
assurance.

(Though, as part of such QA it actually might be a good idea to 
institute some automated checks for repetition and the like between 
successive commits to any codebase... But the syntax of the base 
language, have it gotos or not, ain't then the issue or part of the 
error model; the textual encoding and the likely programmer induced 
faulty string operations on the source are.)

> If someone would like to gather some hard data about whether 
> hopelessly deeply nested if statements is less or more error-prone 
> than using the "goto cleanup handler" style, that would be great. 
> But until that work is done, what I see is a lot of assertions and 
> assumptions.

Also, let's see the performance numbers. As much as we'd like to see 
omnipotent compilers doing miraculous global transformations to program 
flow, especially in C-like low level languages neither the necessary 
semantics for the compiler to do its theoretical maximum, nor the 
willingness of the compiler developer to even try such program 
transformations, just aren't there. Thus, if the programmer is forced to 
do it via nested ifs, the result is often not as fast.

Then not only does the slowdown sometimes matter for real, but perhaps 
even more importantly a large proportion of novice programmers see a 
language which binds them as not worth using. Call it hubris or 
whatever, but if you can't shave off those few cycles whereever people 
want to shave them off, predictably, people will go elsewhere. That's 
really the reason we still have gotos in pretty much every language in 
existence, including many forms of LISP, of all things: if you try to 
force the programmer's hand, he'll fight back, and then all hell is 
loose. Just cf. ADA...

> Testing is like security.  You can't just sprinkle the magic testing 
> pixie dust after you are done implementing, just as you can't (at 
> least not practically) try to add security after the fact, if it 
> wasn't designed in from the beginning.  (Or if you can, it requires 
> infinite budgets....)

On that vein, what would then, in the ideal world, be a) the most 
extensive part of testing you could possibly automate, and b) what and 
how would then be left over to human process? Of course within a cost 
constraint? A sliding scale too, so that you could have various levels 
of reassurance in your product?

Yeah, I know a development framework or two myself. But I don't think 
any real consensus exists about what you should really do, and in what 
priority order, in order to get various levels of assurance. Especially 
when indexed by economic viability, instead of abstract, ad hoc, 
theoretical niceness/beauty standards.
-- 
Sampo Syreeni, aka decoy - decoy at iki.fi, http://decoy.iki.fi/front
+358-40-3255353, 025E D175 ABE5 027C 9494 EEB0 E090 8BA9 0509 85C2


More information about the cryptography mailing list