Departments


We Have Mail


Code Fixes

Two authors who recently contributed articles to The C Users Journal have revised the source code for those articles, providing improvements and bug fixes.

Thomas E. Janzen, who wrote "C++ Classes for Fuzzy Systems," CUJ, November 1993, p. 55, has contributed an updated source file which merges the four listings from the article. The new source includes several modifications, including a provision for command-line arguments, more reasonable behavior for the "open window" example, and a fix for an erroneous type declaration.

Philip Gage, who wrote "A New Algorithm for Data Compression," CUJ, February 1994, p. 23, has contributed a bug fix for his expansion routine, which was printed as Listing 4 in the article. The bug occurs in the statement:

/* Calculate packed data block size */
size = 256 * getc(input) + getc(input);
Some compilers evaluate the two calls to getc in reverse order, resulting in an erroneous value for size. To fix this bug, Gage has broken the statement into two:

/* Calculate packed data block size */
size = 256 * getc(input);
size += getc(input);
The full, revised source code listings for both articles is available on this month's CUJ code disk, and from the various online sources listed at the bottom of page 5.

Dear Mr Plauger,

You have probably already had some mail about Ken Pugh's article in your October issue ("Questions & Answers: Heap or Stack — Which to Use?"), but if not then the following may be of interest. I suggest there are some errors in his answer to Tom Parke starting on page 123 and running through to page 124, and after. Specifically I refer to the declaration

char char_array[NUMBER_OF_CHAR] = "MNOPQRSTUV"
where NUMBER_OF_CHARS was earlier defined as ten.

There are, of course, 10 characters in the string "MNOPQRSTUV", but for a buffer to hold a string of 10 characters the buffer must be 11 bytes in length. The trailing '\0' appended to a quoted string by the compiler will be placed outside of the space reserved with the declaration.

From the substance of Ken's answer I believe he probably intended NUMBER_OF_CHARS to be equal to 11 but (like all of us at some time or another) suffered a "slip of the mind" at the time of writing his article.

What he has done with the subject declaration may not cause any trouble with a single initialization such as the above but it will certainly cause problems with the array of strings which are declared and initialized under the name char_matrix", on page 124.

If readers wish to initialise an array of 10 characters (note: not a string.) to fit the defined buffer, the correct notation is:

char char_array[NUMBER_OF_CHARS] =
{'M', 'N', '0', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'};
where each position in the array is initialized individually.

The error with the size of the storage buffers continues into the use of strncpy (in column 2 of page 124, and after) because Ken is using 10 for the string length (which is correct) but which causes strncpy to append the trailing '\0' to the string stored in the buffer pointed to by, say, p_char. Remember, p_char points to a malloc-derived buffer of size 10 bytes, so the overflow problem persists.

As an aside, it is dangerous to use strncpy to copy less than the total number of characters into a buffer formed by malloc because malloc is not required to zero the buffer. When n, the number of characters to be copied from string s is less than strlen(s) then strncpy does not append the '\0' character to the destination string.

I suggest a better choice might be calloc which, by definition, zeros any buffer space it obtains for the user. This will eliminate any potential problem with the use of strncpy.

I trust these comments will he of interest to your readers.

Yours faithfully,

P. E. Cogar
39 Kalang Road
Elanora Heights
NSW 2101

I think Ken Pugh is correct. You may not know that X3J11 explicitly added to Standard C the ability to initialize an array of three char with a string such as "abc". The terminating null matters only in determining the length of an array of unknown size. Thus, his use of strncpy is consistent. I agree, however, that it is often tidier to ensure that newly allocated storage is initialized to all zeros. — pjp

Dear Dr. Plauger,

I have read The C Users Journal for many years, but I have yet to see the answer to a problem that I have been unable to solve.

I write software for IBM PC compatibles, which does a lot of financial modeling. When I do a performance analysis of my software, I find that it spends an inordinate amount of time rounding my double precision numbers to the cents place. I round just about all of my intermediate calculations in order to be sure that the pennies add up properly. Unfortunately, my best shot at a rounding algorithm (Listing 1) is not very efficient and bogs down my programs.

Do you know of an algorithm for rounding to the penny (or to any decimal place)? Alternatively, do you, or any of your readers, know of a library that contains a function that will help me? My guess is that others may also benefit from this information.

Eric Andresen

P.S. My understanding is that BCD arithmetic is likely to be slow. Plus, I would prefer not to switch to representing the number of pennies rather than dollars because I need to remain compatible with data already stored as number of dollars.

Your trick of adding in SMALLNUM probably helps from time to time, but it's pretty ad hoc. In any case, you have to do about the same amount of work with any sensible method of rounding and converting from floating-point to integer. The greatest speedup occurs when you can switch to an integer representation for currency amounts in cents. If unsigned long has inadequate range, the next best bet is to define a data type that does multiple-precision integer arithmetic. One of the virtues of C++ is that you can then proceed to make such data types behave much like the built-in types, if that is important to you. — pjp

Dear Mr. Plauger,

Regarding the article by Tom Welsh on "Debugging Embedded Systems," The C Users Journal, October 1993:

He mentions a method of loading code destined for EPROM into a block of RAM on a PC and then executing the code in this way to avoid the EPROM burning cycle. He mentions that an EPROM checksum diagnostic stage calculates the checksum and compares it with zero and for the RAM version it uses a pre-calculated constant value.

While writing bootstrap selftest code, I have used a trick that eliminates the need for special-case handling of this checksum value. The algorithm calculates the checksum of all bytes except for the very last byte, which contains the checksum itself, and then compares this with the last byte. The crucial step is to write the calculated value into the last byte before doing the check. With a RAM system this will cause the checksum to have the correct value written to it while the write will be ignored for an EPROM system. With this trick, the process of generating a HEX file and patching in the checksum is removed for RAM-based debugging. A simple code fragment is shown in Listing 2.

If you forward this letter to Tom Welsh or publish it in the letters column I would be most grateful.

John Saunders
28 Dalley Street
Queenscliff NSW 2096
Australia
(saunders@sun1.alcatel.oz.au)

Dear Mr. Plauger:

Thanks for running such an interesting magazine as CUJ.

I'd like to poll your readers for any expertise in Novell's IPX/SPX protocols programming. I want to have a DOS machine talk to a UNIX server process through an SPX connection. They make it to the connection, but I'm having trouble getting send and receive through. I'm basing on Network programming in C, by Barry Nance, and using SCO's TLI programming interface. Does anybody know of an available IPX/SPX packet-level library for DOS?

Any light will be appreciated. Thank you!

P.S. I'd love to find this kind of topics in CUJ.

Eduardo Grosclaude,
Neuquen, ARG
eso@uncoma.edu.ar

Anybody? — pjp

Dear Sirs:

A. Donnie Hale's review of Writing Solid Code (CUJ, December 1993) is laughable, especially his contention that Microsoft's "software is, for the most part, sound and robust." Is this tongue-in-cheek, or is Hale applying for a job at Microsoft?

Microsoft is the only software house that beta tests its programs in the public domain. The facts are well-documented. For example, an early version of Multi-Plan that actually destroyed files (a bug that cost the company a cool $200,000), followed by a version of Word that had no less than 700 bugs (not 7, not 70, but 700). What is more, to this day Word is still buggy (just try to do forms or tables with the damned thing).

Microsoft's system software is even worse. They have owned DOS for thirteen years and (big surprise) it's still a piece of junk. Then there is Windows.... Some have likened this GUI to an elaborate virus designed to slow down and ultimately crash the user's computer, a feat it accomplishes with breathtaking regularity. For a company with this track record to lecture the programming community on the subject of 'writing solid code' is taking the art of self-promotion into the realm of the surreal. But then, Microsoft has never been shy about hawking its imaginary technical prowess to a gullible public.

Hale understates the case when he says "Microsoft is one of the most prominent developers of software in the world today." It is the most prominent developer of software in the world today. But this is hardly a cause for celebration, or even qualified praise. For the dismaying result of Microsoft's dominance is that superior software technology, programs that have withstood the test of time, such as UNIX and X Windows, are so neglected that they never achieve the critical mass necessary for public acceptance.

Your sincerely,

William Fankboner
52-221 Avenida Villa
La Quinta, CA 92253

When IBM was on top of the heap, people said the same things about them. (And they were as adept at patting themselves on the back for their code quality.) I'm sure I said a few bad things about them myself. Nowadays, I'm far more reluctant to characterize anybody's products as particularly good or bad absent any quantitative measures of code quality. — pjp

Dear Dr. Plauger:

With regard to Mr. Hardy's request for information concerning the .PCX file format — some pawing through the bookshelves turn up the following information.

Roger T. Stevens's book, Fractal Programming in C (M&T Books, ISBN 1-55851-038-9, 1989) is the reference for which I originally started my search. Chapter 4, "Saving and Compressing Display Data," states (page 36) that ZSoft Corporation is 'extremely cooperative' in providing information on this format, and further states that the technical support group provided a pamphlet with full technical details. I found this to be true, as I requested, and duly received, just such a pamphlet from ZSoft a year or so ago. Their mailing address is:

ZSoft Corporation
1950 Spectrum Circle
Marietta, GA 30067

Stevens also mentions, on the same page, that there exists an 'excellent' public domain program called ZS, which may be used to display .PCX files, or run a slide show with them. This program is down-loadable from BBSs, or available from the author, at a cost of $10.00, at the following address:

Bob Montgomery
132 Parsons Road
Longwood, FL 32779

Stevens's book itself supplies a description of .PCX header data (pp 37-8) and color map (pp 40-1) and supplies two functions, save_screen and restore_screen, for moving EGA screens to and from disk. Chapter 5 in the same book describes some basic C tools for graphics display, but books which are specifically oriented toward graphics, rather than fractals and their kin-folk, would be of more general use.

Roger Stevens has also written, Graphics Programming in C, which describes an extensive graphics library in more detail. Note that these books are several years old. I suggest going to ZSoft for the most recent file format information.

The book, Practical Image Processing in C, by Craig Lindley (Wiley, 1991, ISBN 0-471-53240-1 and 0-471-54377-2 (w/disk)) is one that I can recommend in this context. In particular, Chapter 6, entitled "Graphics File Formats and Functions," contains a good deal of material which is useful for understanding and manipulating .PCX file formats.

Hope this helps.

And be of good cheer. Please remember from time to time that the people who work the hardest to make a difference are the ones who really do make a difference, but they are also most often the ones who are hardest on themselves about the process.

Remember when you were a kid, how you could look into one end of a telescope and everything looked real big, and then you could flip it around and look through the other end and all the big old stuff was real small? That's called 'changing your perspective.' When the gap between what you believe you should achieve and what you believe you are acheiving gets too big, don't forget to flip that telescope around, okay?

Sincerely,

Lance Latham

Thanks for all the references, and the bit of useful philosophy. Our readers are indeed our greatest asset. — pjp

Hello,

I have subscribed to the C Users Journal since May 1990 and enjoy it a lot and find it very useful. Keep up the good work.

I have just looked through all of my back issues and could not find any articles describing the issues surrounding copy protection (I must note here that an annual subject index would sure be nice). As we are having to face this issue for our product, I'd value some sort of overview of the issues and options. Has CUJ covered this? Do you have any insights?

Thank you,

Brad Ashmore
bashmore@cina.com
CINA, Inc.
P.O. Box 4872
Mountain View, CA 94040 USA
(415) 940-1723

We haven't done an article on copy protection in the last several years. I'm certainly open to proposals on the topic, however. And I do believe that a subject index is now available. — pjp