Back to TOC Departments


We Have Mail


Letters to the editor may be sent via email to cujed@rdpub.com, or via the postal service to Letters to the Editor, C/C++ Users Journal, 1601 W. 23rd St., Ste 200, Lawrence, KS 66046-2700.


Dear CUJ,

There seem to be a number of bugs/misunderstandings in the source code I downloaded from your ftp site today. I'm referring to the source code accompanying Panos Kougiouris' article, "Yet Another Command-Line Parser," which appeared in the April '97 issue of CUJ.

Compile-time bugs:

Run-time bugs:
The program assumes that the first command-line parameter is located at argv[0]. Under DOS, argv[0] is used for the program name and the first argument is stored in argv[1]. Please inform your readers of these bugs in an otherwise excellent program.

— Steve Kut
vecht@ophiropt.co.il


Editor,

This is in response to Julio Kuplinsky's letter in the December 1996 issue about mixing C and C++. You don't have a problem, if you use a C++ compiler like this:

FILE x.c:
extern void f(void);

main()
{
 f();
}

FILE y.C:
#include <iostream.h>

void f()
{
 cout << "I'm c-plus-plus\n";
}

Typing the commands:

g++ x.c y.C
a.out

yields the output:

I'm c-plus-plus

But typing, as the letter says:

gcc -c x.c
g++ -c y.C
ld x.o y.o

yields:

ld: warning: cannot find entry symbol
  _start; defaulting to 08048080
x.o: In function 'main':
  x.o(.text+0x4): undefined reference to 'f'
y.o: In function 'f(void)':
  y.o(.text+0x9): undefined reference to 'cout'
  y.o(.text+0xe): undefined reference to 'ostream::operator<<(char const *)'

I can't even get it to link. I don't know why you were able to.

Marty Leisner
leisner@sdsp.mc.xerox.com


Dear Dr. Plauger,

In a few months my subscription to CUJ will expire, and after many years I will not renew it. Not because anything CUJ has done wrong, on the contrary.

I have always been a hobbyist programmer, since I first got my hands on a teletype terminal connected to a timesharing mainframe in 1968. Over the years, I got my very own computer, starting with the venerable Timex-Sinclair, and as my computers got more powerful I learned more about programming. I graduated from Basic to Pascal and hence to (Turbo) Prolog. This challenging language was more fun than any other language I ever used before or after, at least once I learned to think recursively.

But the shortcoming of (Turbo) Prolog was its inability to handle databases gracefully. The answer was to interface it with C-language subprograms, so I set out to learn C and gradually forgot about Prolog. Over time I drifted into C++, still of interest because again it involved a new programming paradigm, object orientation. All these years I never programmed for a living, although I taught some semesters of introductory C and C++ at our local state university.

But just like the years of radio hobbyists and shade-tree automechanics are past, programming has become a complex, time-consuming, and ultimately dull occupation, best left to teams of professionals. Worse, just like the Space Shuttle is a complex, but essentially dull successor to the magnificence of Saturn V and its journeys to the moon, C++ in all its complexity has lost the magic of the early simpler languages. And just like the Space Shuttle can still be brought down by minor glitches, C++ still suffers from treacherous pitfalls that can cause complicated programs to crash disastrously.

To cap it all, DOS is dead for all practical purposes and Windows, this infamous kludge, forces further unrewarding complexities on the hapless programmer without adding to the essential merits of his program.

In short, I've had it with C++ programming. Maybe I can recover the fun I used to have by going back to Prolog and interface it with C, as I intended originally. Or maybe a new language will generate excitement again, be it Java or something else. Whatever the case may be, I'm out of here, but I certainly wish you and all the contributors to CUJ continued success and fortitude. It's been fun while it lasted!

Regards,
Willem F. Borman
wborman@compuserve.com

We are indeed deep into an era of complexification, and I share your distaste for it. I stopped writing compilers and switched to writing libraries for many of the reasons you cited — I prefer bite-size projects that are fun to managing complexity issues seven hours out of every eight. There's still fun to be had in C, and even C++, if you look for it hard enough. But I do sympathize with your position, and I appreciate your taking the time to express it so clearly. We'll miss you. — pjp


Editor,

In the January 1997 issue, in the reply to the query from dan@bay.nrl.navy.mil regarding the timer class, you recommend the use of difftime when the code is described as normalizing values using CLOCKS_PER_SEC.

As values converted to seconds using CLOCKS_PER_SEC are presumably of type clock_t (returned from clock or from Posix times), I believe that double difftime(time_t, time_t) operating on time_ts would would not be appropriate.

Alan Peakall
OSM Ltd
alan@osm.co.uk

Whoops, perhaps I misspoke. difftime returns the time in seconds as a double, given times of type time_t. But CLOCKS_PER_SEC works with values of type clock_t, which are not necessarily the same flavor. Thanks for the correction. — pjp


Editor,

In your C/C++ Users Journal, Feb 1997, you had a question from Juan Perez about source code platform compatibility between PC (I assume Windows 3.1, Windows NT & Windows 95), IBM AIX, Solaris Unix, HP UX, etc. I had searched extensively for this very thing for our applications. Microsoft turned me off because their compiler no longer supports Windows 3.1 applications! I also tried several different interface providers, but the cost is prohibitive unless you are willing to spend $2,000-$10,000 per platform. Several companies claimed the capability, but you must use the native compiler and they would not say that you would be able to compile on every platform without source code changes.

I then found the IBM Visual Age C++ compiler which is provided by "Big Blue" on all of these platforms at a very reasonable price. They have been very helpful and I have had very few problems converting my MSVC++ programs to compile with their compiler (including MFC). The only serious problem has been with the Windows Help files which are not compatible with the Unix systems. Other than that little problem, the porting is simple — copy the source code and recompile. This is what I call transportable applications.

Marc Pottorf
Geotrace Technologies, Inc.
Software Products Manager

Both IBM and Microsoft are now customers of my Standard C++ Library, so I tend to be ecumenical in this area. But I agree that the Visual Age C++ compiler is an underutilized resource. It is a remarkably clean, fast, and flexible compiler. Given the (deserved) popularity of Microsoft's Visual C++, IBM's offering hasn't received the attention it too deserves. — pjp


Dear Sirs -
I'm submitting the code in Listing 1 as an alternative to the implementation given in the article "A Polled Timer Class" in your February 1997 issue. For simplicity, in this example only one timer is implemented (lastRxBlkTime), and it is constantly running and being restarted until the specified timeout occurs, which is then handled as an exception condition cleared by resetting the hardware. The macros used to determine that a timeout has occurred should work on any hardware platform that represents signed integers in two's-complement format. What makes the macros work is that -1 is represented as 0xFFFFFFFF in two's complement arithmetic, which also happens to be the highest unsigned value that a 32-bit counter can count up to. Add 1 to 0xFFFFFFFF and due to 32-bit overflow, you will get 0, so 0xFFFFFFFF does behave like -1 in a modulus 232 fashion.

Sincerely,
Ed Remmell,
Software Engineer
Cincinnati Microwave
email: eremmell@cnmw.com,
aka mithras@erinet.com

Thanks. — pjp


Editor,

Greetings. Regarding "Stack Considerations" in David Taylor's article, "Interrupt Thunking," (CUJ, March 1997, page 41), where the author notes that hardware interrupts can occur when any program is running, and such a running program may not have a large enough stack — true enough, but MS-DOS, at least, has for a while provided a mechanism to deal with this: the CONFIG.SYS STACKS command.

From User's Guide and Reference, MSDOS 5.0, 1991, page 570, describing the command: "Supports the dynamic use of data stacks to handle hardware interrupts." Also in later versions, which essentially have no documentation, try the on-line help stacks. Up to 64 stacks of up to 512 bytes each are available; the system normally defaults to nine 128-byte stacks. Sixteen-bit Windows almost certainly continues this tradition, although I can't swear to it. As far as I can tell, applications don't do interrupts in 32-bit Windows.

I should note that an early implementation of STACKS, in some versions of MSDOS 3 I believe, are pathological, and the command should not be used in those systems (after a certain number of interrupts, the system stops).

Well-made programs might still switch stacks for hardware interrupts, particularly if the programmer knows his code has large requirements (large local structures/arrays in called code, recursion etc.). But for many applications, it's probably just as well to let the system do it.

J.G. Owen
71121.625@compuserve.com


Dear Dr. Plauger,

Having read the December "Editors Forum" in CUJ, I enthusiastically went to the Dinkumware site to have the Antipodeanally vernacularised look that you suggested we do.

Whilst you disclaim authorship to the design and arcana (well, thanks to Microsoft's impetuousness with FrontPage it's becoming mundana), I somehow suspect that you have had a neat hand in the funnyhaha sidebars on the pages of the Dinkumware Web site.

As an Aussie, a smart-alec, and a programmer, I congratulate you on your humourous efforts — unlike those teeming millions, you have created a site that is not only informative and of priceless worth to the C/C++ community, it also brings a huge wry grin to our faces as we navigate too!

You'd be aware of the strange way Australians view their USAian cousins, and as all I know is that you spent time in Australia, I needn't attempt to insult you by asking where you spent your childhood — for indeed their is no need.

You have the Australian wit down to a tee and among the relatively few who live in the States whose Australianisms make me laugh because they are so true to form (whether cynically or otherwise). While not particularly manifest on his site, my good friend Duncan Dwelle (http://www.aisintl.com/) is another of those gems in the IT industry who is informed, articulate, and jocular.

If you're looking for ideas for further sidebars, I'm sure the cybernetwork of Aussies who follow your columns would be more than happy to inspire.

Many regards and thanks for your long-standing contributions,

Joshua Graham
jagraham@ozemail.com.au

I confess that I also got e-mail from another Aussie who took offense at some of our distorted Australiana. When I explained that it was all a joke, he replied, "Oh, humour. I thought you were merely stupid." It averages out. — pjp


Editor,

Regarding Tactic No. 2, the dotty old chalkboard college professor knew far more about leaking memory than he let on. ("How to Leak Memory in C++, CUJ, March 1997.) In fact, he uses a stealth technique. The danger of the example given (with the returns in the case staement) is someone might spot the delete pThing at the end of the example not being called and fix it. Using the single return statement at the end of the function gives the illusion of safety, but...

bool AdjustTemperature( HTHING hThing) {
  Thing * pThing = new Thing ( hThing); bool returnValue = false;
  switch (pThing->Color( ) )
{
    case BLUE:
      AdjustTemperature( 5 );
      returnValue = true;
      break;
    case RED:
      AdjustTemperature ( -5 );

But just when you thought it was safe, it turns out that AdjustTemperature throws an exception if the argument is negative, the exception goes flying out of the block, and hThing leaks away.

What's really needed is something that automatically deletes pThing whenever the function exits, regardless of whether it's a return statement or an exception. Sounds like an auto_ptr to me. You can find a copy provided by Scott Meyers at http://www.aw.com:80/cp/mec++-appendix.html.

Gerard Weatherby
gerard.weatherby@snet.net

You can also find one with the Microsoft VC++ V4.2 or later compiler. It's part of the Standard C++ Library. — pjp


Dear Dr. Plauger,

This is in response to Vince Pachiano's letter in the March 1997 CUJ, concerning the design of the ASCII character set. I dare say this short letter from Mr. Pachiano will generate more responses than some of your longer, knottier problems, but this one I know (or think I know) something about having been involved in this game since an undergrad P-Chem lab in 1963 (FORTRAN 2b on an IBM 1620!). I definitely understand your comment about EBCDIC because I wrestled with sorting things alphabetically before I ever came across ASCII. It worked fine on a card sorter but when those 12-, 11-, and 0-punches were converted to 9 bits... But I digress!!

I don't know this from having seen it in print anywhere, however, I suspect that the designers of ASCII were far more concerned with sorting and upper/lower-case things than a contiguous ASCII representation of the hexadecimal character set. Consider the following: The hex representation of the decimal digits [0-9] is x30-x39 (probably useful). Similarly, [A-Z] is x41-x5A. And [a-z] is x61-x7A. A single bit, x20, converts every uppercase letter to its corresponding lowercase letter.

The lowercase alphabet is easily converted to the uppercase alphabet by the inverse operation of masking off that same bit. Making the uppercase alphabet contiguous with the lowercase alphabet would not allow this very convenient operation! As for the non-contiguity of the decimal digits with 'A', I suppose the digit-run could have been made contiguous with 'A' by using x37-x40(!?), but then we would lose the hexadecimal/decimal digit similarity, viz., 0-9 and x30-x39. Maybe it's not that useful. Perhaps one of the original designers could enlighten us. Perhaps you're right about "communications types." Nevertheless, it does appear that the convenient upper/lower-case conversion was intentionally brilliant.

I've been meaning to write ever since I caught you in a few grammatical and usage errors (They were very hard to find!) in "Programming on Purpose" in the erstwhile Computer Language [now our sister publication Software Development,, in its current incarnation — pjp]. I thoroughly enjoy your writing style and, of course, protestations in this Letters Department to the contrary notwithstanding, this journal is the only one I receive that is always worth reading cover-to-cover!

Lee Stewart
lee.stewart@juno.com

Sounds like I started programming about the same time you did. After wading through numerous incompatible six-bit character codes, all vendor-specific, I thought both ASCII and EBCDIC were godsends by comparison. I long since learned to forgive both their little peculiarities. — pjp


Dear Editor,

I have recently been reading a book on advanced iostream programming. In the book, the author puts forward a method for using iostreams with serial ports. However, he notes that iostreams do not allow configuring of the port. To bypass this problem he creates a class which uses containment and the ioctl interface to configure the port.

Unfortunately, the example uses the OS/2 specific ioctl function

DosDevIOCtl (DeviceStream.fd(),
   ASYNC_SETBAUDRATE,
   (PULONG) &BaudRate,
   sizeof(BaudRate),
   &PacketSize,
   NULL, 0, NULL)

Here, DeviceStream is an ofstream object to the com port, BaudRate is defined as a USHORT, and PacketSize is defined as a ULONG. The function returns an APIRET value. My research has shown that DosDevIOCtl is portable to the DOS platform, however, Borland C++ V5.0 Help defines ioctl as

int ioctl
  (int handle,
   int func [, void *argdx, int argcx])

which is passed only four arguments to DosDevIOCtl's eight. How would I port this call to DOS, or is there another way of handling the configuration of COM ports without using bioscom?

On a different note, would you know of any good sources for information on DOS mouse programming in C/C++?

Mark Bidewell
mbbs@voicenet.com

ioctl was born under Unix, as a generalization of the earlier stty and gtty system calls. The whole lot has suffered from inconsistencies and system-dependent specializations since it was born. Don't let the commonality of names fool you. What I always do, when I have to muck at this level, is track down the system-specific description of any port-configuration tools and fiddle with them until I get the desired effect. I then encapsulate the problem code in a function with a more portable interface, label it as such, and cross my fingers.

For mouse programming, you can try your luck with the CUG library for enlightening code[visit http://www.hal9k.com/cug mb]. If you want tutorials, I suggest you devote an hour to browsing at your nearest comprehensive computer book store, until you find the tome(s) that has the proper impedance match to your particular needs. (Of course, this is my generic reply to most requests for book recommendations.) Good luck. — pjp


Editor,

I have been subscribing to CUJ for half a dozen years. I've just read your "Editor's Forum" in the April issue. I completely agree with you. The message included below, which I recently sent to Mark Schlack (Byte's editor in chief), Jerry Pournelle (Byte's senior contributing editor), and Jon Udell (Byte's executive editor for new media), points out another source of hidden costs — and explicit frustration — for Internet users:

"Companies are investing considerable resources for developing their Web sites. A substantial fraction of these resources is allotted for providing customers with good reasons for frequently visiting the sites: useful or interesting information, audio or video broadcasting, news feeds, free software and documentation, and even entertainment. This is certainly a blessing, but it often turns into a curse and a source of frustration.

"Not everyone — even in developed countries — accesses the Internet through high-speed corporate links. A slower and less reliable dial-up PPP account is common among individual users. When they download large files, — Web browsers from Netscape and Microsoft, the Java Development Kit, etc. — the transfers are often unexpectedly interrupted before completion because of network problems. It doesn't take a marketing guru, or a useability lab, to understand why this source of customer frustration is not beneficial to the image of themselves that companies distributing large files try to create.

"A possible technological solution to this problem involves the use of restartable file-transfer protocols, servers, and clients. But there's a simpler and inexpensive one: making versions of large files split into more manageable chunks — 1 to 1.5 Mb each — available for downloading besides the full ones. Given the decreasing cost of disk storage, this is not going to bankrupt any company. And the brainwidth required for implementing such a solution is negligible.

"All of you are well known and highly respected authorities in the computer industry. If you think that the problem I've pointed out is worth your attention, you might use your influence to let your wide audience know about the disadvantages of distributing large files over the Internet. What about, for example, a sort of 'slim files only' logo for Web sites, or a new category for the Chaos Manor Orchid and Onion parade? This would be a small step for you, but a big step for netkind."

Thank you very much, by the way, for mentioning Thomas J. Lindsey in your "Editor's Forum" on the July 1992 issue of CUJ. As you may remember, he's the author of the C Programmer's Quick Reference T-shirt, which is printed upside-down. We have been corresponding by email since then, and we became good friends.

Kind regards,

Paolo Amoroso
amoroso@mclink.it0