[Cryptography] GnuTLS -- time to look at the diff.

Nico Williams nico at cryptonector.com
Fri Mar 7 16:19:02 EST 2014

On Fri, Mar 7, 2014 at 2:04 PM, Patrick Chkoreff <patrick at rayservers.net> wrote:
> Harald Koch wrote, On 03/07/2014 01:49 PM:
>> Anyone hung up on goto should learn that you can write the same code with:
>>     do {
>>        if (something fails) {
>>           break;
>>        }
>>        ...
>>     } while (false);
>>     /* cleanup code goes here */
>> This has no goto, but it has exactly the same failure modes as the
>> goto-laden code (btw, if you're looking for a "goto cleanup;" equivalent
>> in Java, this is how you do it).

Exactly.  It doesn't speak well for Java that you need all this extra
ceremony to get a simple "bail out" pattern.

> Yes, I like that.  It's a highly malleable technique, in the sense that
> you can easily nest it or move it into a separate routine.


 - compilers that whine about constant loop conditions (oh but why?!)

 - unnecessary and distracting additional indentation...

 - ...which increases the pressure to refactor into pointless 3-line

 - ...which increases the number of units to think about / devalues
the function/method as a unit to think about.

The pressure to indent / pointlessly refactor is a big deal, a very
big deal.  We're talking about codebases between hundreds of kloc and
tens of mloc, and engineer teams with turnover rates too high relative
to the size of the codebases.  That means that the task of _reading_
the bloody code has to be made simple.  The use of goto in the Apple
code achieved that, and all the alternatives being proposed would undo
that achievement (for shame).

Making that code easy to read wasn't sufficient to avoid a bug because
no one actually read the result of a merge (or something along those
lines) carefully enough, and that might not have been sufficient
because humans are fallible.  Lack of testing did this in, NOT this
use of goto.

> It's almost like a code block which returns a value -- a feature that C
> doesn't actually have.  Instead of a return value, you can declare some

Yeah, yeah, statement expressions, yeah, yeah :)  I like them, they're
nice.  They're not universally available, and neither are
indefinite-extent closures (Blocks).  And we're stuck with C, so of
course we want these things.  (And CoreFoundation, which proves you
can get decent data structures and memory management in C.)

> auto variables before the "do", and have the loop body set those
> variables fully, or partially in the case of a break.  If you make sure
> to initialize the auto vars to 0, which is easy to do in C, then the

Well, no, it's not easy: you _have_ to initialize them because they
don't auto-initialize.

One can do something about this: put all local variables in a local
struct and memclear it at function entry.  Of course, that doesn't
work for pointers (since zero pointer values need not be zero bit
patterns, though for most architectures they are zero bit patterns, so
maybe you won't care).  Or you could use a macro to define local
variables and auto-initialize them to zero (which doesn't work for
structs, but hey, at least that's a bit of progress).  Of course, now
the code doesn't really look like C... (maybe that's a feature).

> presence of 0 values can itself indicate certain failure modes in the
> code below the "while", after the (one-shot) loop ends.

Seriously: the goto was not the problem.  Building a lot of machinery
to avoid a non-problem is only going to cause problems.

Admit: software engineering is hard.  There are no obvious, simple
answers.  There are no non-obvious, simple answers either.  Stop
looking for simple answers: there aren't any.  Software engineering
requires discipline.  Software engineering is expensive.  You get what
you pay for.

If you're not paying for discipline then you'll need a scapegoat; I
suppose goto is as good as any other scapegoat.

But I'll call you on it.


More information about the cryptography mailing list