[comp.lang.c] C style, continued

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/14/88)

Here's something that bit me a couple of days ago;
I hope that a warning about it will help some of you
avoid a certain class of problems.

I had written a (very spiffy!) sorting utility for a previous
project.  When our current project needed to sort (potentially
large) files, I quite naturally modified a copy of my older
program, and fork/execed it to do the sorting.  When we
found that the spawning overhead was going to be intolerable,
I then had to decide whether to turn the program into a
subroutine or to spawn a single sorting slave that would
keep a pipe open to the master process and sort files upon
request.  Fortunately I already had a package (of functions)
for master/slave communication, so the latter was feasible.
So far, so good.  However, now the bug bites.  Because I
KNEW when I originally wrote my sorting program that it would
be sorting exactly one file, I had relied on static (compile/
load time) initialization of several variables.  Of course I
knew that I would have to fix this when I was converting the
program to handle multiple sorting requests, and I made the
initialization of the file-scope statics dynamic (run time).
The resulting code handled small test cases okay, BUT it
broke badly when I tried it on a large test case (many sort
requests).  [Side note: Because about 30% of my code was
"assert" statements, when things did go wrong I was able to
spot the problem immediately and had good clues as to the
causes.]  It turned out that in several cases I had used
block-scope initialized statics, not just file-scope ones.
These too had to be changed to dynamic initializations.

There are a couple of lessons that could be learned from the
experience.  [The value of liberal "assert"s is one of them.]
The apparent moral is to not use block-scope static
initialization, but I think a better one would be, to design
utility programs with the thought that they should be
serially reusable.  That way if they ever become subroutines
(or repeating slaves like the one I had) you already have
them in shape for the task.

maart@cs.vu.nl (Maarten Litmaath) (12/16/88)

gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
\The apparent moral is [...] to design
\utility programs with the thought that they should be
\serially reusable.  That way if they ever become subroutines
\(or repeating slaves like the one I had) you already have
\them in shape for the task.

So use fgets() instead of gets(), Doug? :-)
-- 
fcntl(fd, F_SETFL, FNDELAY):          |Maarten Litmaath @ VU Amsterdam:
      let's go weepin' in the corner! |maart@cs.vu.nl, mcvax!botter!maart

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/17/88)

In article <1816@solo10.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>So use fgets() instead of gets(), Doug? :-)

That has nothing to do with the topic.