[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