Departments


We Have Mail


Dear CUJ:

It was with interest that I read the article by K.B. Williams in the July issue on Testing Sort Routines. It was unfortunate that Williams was unable to compile TSTSORT.C under Borland C. Since many compiler implementations will optimize code differently, I would question any comparisons of results of the routines run under Borland C versus Microsoft. A matrix of results under Borland versus Microsoft would be more satisfactory.

I was able to compile under Borland C/C++ v 3.1. The principal impediment was a group of preprocessor if statements:

#if defined (__STDC__) || defined \
   (__PROTO__)
to which I appended | | defined (__BORLANDC__), since I chose to use selected C++ extensions such as the // comments.

Additional Standard C compatibility items are:

1. Microsoft C is more forgiving in the use of

   #include <header>
versus

   #include "current-directory-header"
2. Even in the large memory model 65536 was far too large for the variable >MAX_SORT. One fourth the size was better. This may be a problem in memory options on my BC3.1 implementation. An "oversized global data area" message required that I cut the size again by half to 8 K.

3. Non-ANSI routines such as _strupr are implemented in BC without the underscore prefix. Some redesign of the code could avoid this problem entirely by using standard routines stricmp and strnicmp or toupper for testing strings and characters. DOS time routines and structures are implemented with an underscore under MSC. _timeb and _ftime are among these.

4. Prototypes for functions CmprFun and GenGausRand are missing from the routines invoking them.

5. The macro for MK_FP to create a far pointer differs in BORLANDC. Here I opted for the default BORLAND definition.

6. The macro variable, TEST, needs to be defined in HSORT.C to include a main module.

Algorithms in C, by R. Sedgewick has a more economical siftdown, or as he calls it downheap. In his version he saves the initial data and pointer or index. In the loop, data is saved until the break condition and then the hole is filled with the saved data. Almost half the data movement is saved. A final data restoration may conditionally be eliminated by a test, when no middle semiswap is performed.

Data dependency for larger structures and data strings is reduced by sorting pointers to the strings or data structures. In this way larger structures have time dependency for input and output and for comparisons but not for swaps.

Sincerely,

John R.B. Brown

K.B. Williams replies:

I knew some ambitious Borland C programmer would come to my rescue. Thank you. There were just too many compatibility issues to be solved to make it worth my while. The issue, in any case, was testing sort functions, not a compiler optimization contest.

I would be more that a little interested in hearing how the tests fared under Borland C, especially the case of 50,000 four-byte items. I would also like to see a comparison of the Sedgewick approach mentioned above with one or more of the others in the article.

With respect to Item 4, the only function that invokes the named functions directly is tstsort. In my copy of the code, the prototypes are near the front, lines 27-53.

The answer to Item 6 in this litany of problems is satisfied in the makefile which I used assiduously. Variable TEST is defined at line 20 of the makefile. The makefile also defines the variable __PROTO__ at line 17 of the makefile. This makes the prototypes visible to all comers.

Compatibility issues are likely to be with us forever. To quote Steve Rimmer in Multimedia Programming for Windows:

"Observing formations of pigs flying south for the winter is several orders of magnitude more likely than having two competing C compilers deal with more than eight lines of source code the same way."

K.B. Williams
Kbwms@aol.com

Dear Editor,

I recently renewed my subscription to your fine magazine. Keep up the good work!

I have been programming in C for nine years and C++ for three years. At the risk of being an iconoclast, I keep thinking I am seeing fleeting glimpses of anatomy through Emperor C++'s finery. It seems that the programming world is racing like lemmings over the C++ cliff and is, in the process, leaving a very good thing behind.

I taught myself to use C++ because of all the good things it could get me. It allowed me to exploit application frameworks, albeit with a steep learning curve associated with each new framework. It seemed that I was spending more and more evenings and weekends curled up with application framework manual du jour. Now I am wondering if these application frameworks are all they are cracked up to be.

As an example, a recent issue of Microsoft Systems Journal had an article which described the message and command routing of an industry-standard application framework as "labyrinthine." In the old days (last year), we wrote a window procedure (generally, a several page-long switch statement) to receive and deal with messages and events. Now, we have to worry about message maps and virtual functions. I do not see much difference between writing a bunch of code in a switch statement and writing the same bunch of code in a virtual function. In the old days, I could be sure that whatever happened, it happened in my switch statement. Now, there is more complexity to deal with, with more uncertainty associated with it. I am forced to put a lot of trust in the work of others. I am not certain that this is good. Additionally, in my humble and subjective opinion, it seems that the application framework code is more difficult to maintain.

I once had an embedded application that had to fit onto a small flash RAM. I wrote this simple application in C++, and, to my horror, it would not fit onto the flash RAM. I rewrote it in C (over a weekend), and had room to spare. After being the office's C++ advocate, I had to endure some jeers. This did make me realize, however, that inherent in C++ are some traits which make it questionably suitable for certain applications. We should know what penalty we pay by the use of such C++ attributes as runtime binding before we use them in a time critical function such as a power-down interrupt handler.

What this points to is the possibility that C++ is not always the appropriate tool, and that, for many situations, C remains a perfectly appropriate solution. CUJ does a wonderful job of convering the "how" and the "what" of C and C++. I would like to hear your ideas on the subjects of "when," "why," and "whether" to use C or C++.

Perhaps CUJ could in the future take a reader survey or provide some form of metrics that would quantify what size or type of project is best served by which language. I would like to see a big picture view of the use of the respective languages. I realize that this may a difficult subject upon which to gather objective data, but a preponderence of subjective data, even anecdotes, would be a good start.

Thank you for enduring my whining. Again, thank you for a fine publication.

Best regards,

Rod Doe
76360,3365@compuserve.com

As long as we have readers as open-minded as you seem to be, we're in good shape. I suspect you'll find Bobby Schmidt's new column, "The Learning C/C+ + urve," highly relevant to your needs. He will be tackling just the kind of questions you raise, including the "when," "why," and "whether." You've also brought up another very important point: there's no need to program exclusively in one language or the other; in fact, many of us cannot afford such a luxury. Rather, we find that each language works best for certain kinds of projects. With some care it is also possible to mix C and C++, and should you endeavor to open that particular can of worms, we will be here to help you avoid the pitfalls.

We've heard lots of complaints in these pages about both C and C++, but I can't recall receiving any letters from readers sharing their experiences in choosing between the two on a project-by-project basis. How about it, readers? — pjp

Editor,

Where I can find the C+ Standard Draft ? Is this draft available via anonymous ftp in Internet?

Best regards

Andrew Montefusco

(I am a CUJ reader: very good work !)

Here's the list Tom Plum recently sent me, in response to a similar request:

Here's a selection of URLs:

Most sites have the working paper in PostScript form and in Adobe Acrobat form. The cygnus site has an html version of the working paper. lf any of the sites has access restrictions, or has been discontinued, just try one of the other ones.

Dear sir,

I read with great interest your article in the C/C++ Users Journal about the string class and its many features. I am eager to start using this class when possible, because doing so would simplify writing the text processing programs I frequently write.

At first I mistakenly thought it was included in the STL, so I downloaded HP's free implementation of the STL. How disappointed I was when I discovered that the string class was not included! Is there a spot on the Internet where one can follow the current proposed standard?

Do you know of any way to access an implementation of the string class you described, or similar to what you described? How about other classes in the draft Standard C++ Library? Or just the header files?

Thank you for your time. I really appreciate your leadership in the C and C++ communities, and your helpful and concise articles and books.

Sincerely,

Leo Manuel
Lmanuel@comptons.com
LManue12@aol.com

You can buy a copy of my version of the Standard C++ library from either R&D books in Lawrence, KS (now a part of Miller Freeman, Inc., the publisher of this magazine) at rdorders@rdpub.com or from Plum Hall in Kamuela HI at sales@plumhall.com. The folks at Cygnus also seem to be building up a copyleft version for Project Gnu. More than one vendor of repackaged STL code tosses in a string class along with the code from Hewlett-Packard. Code is seldom completely current, because the string class keeps changing, but you can get a reasonable facsimile.

As for tracking the draft C++ Standard, comp.std.C++ is the public arena for discussions. The reflectors used by the standards committees have restricted membership.

Thanks for the kind words. P.J. Plauger

Dear Editor,

On page 37 of the August 1995 issue of The C/C++ Users Journal, Peter Heinrich and Nathan Dwyer write: "Thus, fixed-point operates at almost exactly the same speed as the integer equivalent. Generally, this speed is several orders of magnitude faster than floating-point, with or without an FPU." Generally, this is no longer true. For some architectures, the "several orders of magnitude faster" is incorrect. For others (such as the PowerPC), the "faster" is often wrong.

On page 47, Dave Gottner writes: "Unfortunately, templates allow one to reuse source code only." There is nothing about the draft C++ Standard that mandates that instantiations of a non-inline (possibly member) function template with different template arguments need result in completely separate object code. It is the current generation of C++ compilers, not C++ templates, that imposes this restriction.

Regards,

Atman Binstock
ajb@panix.com

Both of your observations are correct. It is difficult to make a blanket statement about either computer hardware or software that is universally true, particularly in the current rapidly changing marketplace. pjp

Dear pjp,

I missed the book-review fracas that triggered Martin Weitzel's excellent letter (CUJ, September 1995), but here's my zloty's worth on computer books in general and C/C++ books in particular.

First, authors seldom have much influence on the publisher's marketeers. The blurbs and titles are devised to sell in an overcrowded market regardless of the shame inflicted on the author. Of course, big sales and royalties readily dilute the shame. The publishers have carved up the market by means of titular templates. Thus Sybex own Mastering X and Understanding X, Coriolis exploit Zen of X, and IDG have grabbed X for Dummies in a big, dumb, sucessful way. Indeed, the mighty MIT Press had to back down after they had advertised a forthcoming Big Dummies Guide to the Internet. (It was renamed Everybody's Guide... which must have upset Chomsky.) In the search for untapped templates, publishers are now reduced to The Best X Tips Ever, X for Complete Idiots, and even (borrowing from those dishonest natural-language systems) X in Seven Days.

Thus, one of my own modest Sybex books on C, intended as a gentle introduction for the absolute beginner, emerged as Mastering Turbo C. There was some consolation in finding that the Portuguese edition bore the sexy title Dominando O Turbo C!

Second, re-Martin's point about syntax errors in published program examples: The sad/true fact is that the most pristine ASCII code, fully linted and tested, can be mangled in its passage from the author's disk to the printed page (both book and magazine — nudge, nudge). C/C++ code is especially vulnerable: spurious line breaks can appear in one's // comments, and when reading an unguarded tilde many a typesetting system escapes into its own strange universe. A particularly annoying quirk that can be hard to spot is that the decremental double minus is often translated as an em- or endash. Since a single ASCII hyphen provides a pathetic minus sign in many fonts, some publishers ask for two hyphens per proper minus and hence four hyphens for a decrement.

Finally, we must distinguish works of reference, tutorials, and those that attempt both. In each class, we find both general books and those devoted to specific compilers/platforms. In current parlance, these categories demand different judgmental methodologies.

While K&R, H&S, and ARM are essential for mastering C/C++, they were not intended to motivate and teach the beginner. A text for the beginner should, of course, avoid blatant errors, but there are many situations where a first gentle pass at a topic (say, arrays or function declarations) will almost certainly infuriate the "expert." If the author peppers the text with detours, provisos, footnotes, disclaimers, or "but see Section X.a.ii for the real truth,.. you can end up with the accuracy and unreadability of an ANSI standard.

PAX etc.

Stan Kelly-Bootle

PS: In addition to UNIX Review and OS/2 Magazine, I'm now writing for "Cross-Platform Strategies" (SIGS Pubs., starting September 1995) and "Software Development" (MillerFreeman, starting October 1995) — whence the VFAQ (very frequently asked question): "Who has more columns than the bleeding Parthenon"

PPS: My Computer Contradictionary (MIT Press) is now in the shops.

It is said in science-fiction circles that there are short stories, and then there are lafferties. If you've ever read a short story by Ron Lafferty, you soon understand what this means. In our business, there are letters to the editor and then there are kelly-bootles. 'Nuf said. pjp

Editor,

After reading your description of the <string> header ("Standard C/C++," July 1995) I am concerned. You state that as of now, "The classic minimum program ... now drags in several thousand lines of headers." While the compile time of this concerns me a little, the concept of precompiled headers which a lot of compilers support today should ease that pain. But what is the effect of these cross-class references on optimizing, or smart, linkers? I suspect that in the statement:

cout << "hello, world" << endl;
only a small part of the string and iostream classes are actually involved. But will optimizing linkers be able to recognize that and remove the unused string and iostream code?

This concern goes beyond the Standard C++ libraries, of course. I have run into this problem on the Mac with Symantec's otherwise excellent C++ product. Their Think Class Library (MFC for the Mac in effect) is so cross referential that an application can end up taking a lot of disk space even when it is used only to put a simple window up on the screen. MFC itself is so similarly bad that Microsoft sidesteps the issue by allowing you to share the base MFC code via the MFC200.DLL, MFC250.DLL, MFC30.DLL, etc. files !

While this is clearly out of the scope of the standards effort, I would like to ask you and all the CUJ readers to keep pressing their vendors to deal with this unnecessary code bloat and find ways to remove truly unnecessary code.

Steven Kienle
sckienle@pwinet.upj.com

It has indeed been the attitude of the C++ standards committees that customer pressure will force vendors to eventually compensate for the "challenges" raised by the evolving draft C++ Standard. pjp

Dear pjp:

While rewriting Brian Tagg's problem(April, 1995), Richard Howells transformed the code in a way I don't understand (maybe because its a snippet instead of a while function). What's the matter with this:

char string[MAXLEN];
   while (1) {
   fgets(string, MAXLEN, stdin);
   /* ignore fgets test for failure */
   if (string[0] != '\n')
           break;
   puts("Entering a blank line won't
        cut it.\n"); }
This is both clear and efficient (fgets is called once). We have a forever loop, so to break out of it is expected.

marty leisner @ sdsp.mc.xerox.com
Member of the League for Programming Freedom
(http://www.lpf.org)

Yes, the solution you both espouse is one of the forms I sometimes fall back on. The other is to encapsulate a nontrivial chunk of code in a function, then repeat calls to the function as needed. pjp