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.