Sirs,I felt impelled to write a response to Mr. Eberhardt's letter in the April '93 CUJ. As President of Strategic Software Designs, Inc. (SSDI), I was very dismayed that we had such an unhappy customer and somewhat surprised by Dr. Plauger's response to that person's letter. In the first half of 1992 we had a number of problems with Airmail and ground deliveries to Canada. Most of these problems were solved by re-shipping product via UPS International Air service where we could track each shipment exactly. Because of these shipping problems, we instituted a strict policy of only shipping via UPS Air for ALL international shipments. Since this policy has been in effect we have experienced no problems. In the process of re-shipping products, Mr. Eberhardt's product was not re-shipped. I cannot re-create exactly how we missed re-shipping this product but it was probably due to a mistake in our shipping department. I am personally calling Mr. Eberhardt to do whatever I can to remedy his situation. As with any small software company SSDI is not perfect but, in answer to Mr. Eberhardt's question, yes there are 300 (and more) satisfied users of _miniEd products and we are going to re-double our efforts to minimize mistakes and guarantee that we promptly respond to the needs of our current and future users.
Paul Kovac
Strategic Software Designs, Inc.Robert Ward, CUJ Publisher responds:
Thanks for writing, I appreciate your candor.
In all honesty, on second reading, we're not very proud of our response (see this month's Editorial Forum). I apologize to you and to our readers for not doing a better job of living up to our own standards.
I would have preferred that our response had spoken in defense of your motives. Personally, I'm bothered by what appears to me to be a growing willingness to assume the worst of anyone who is in business. I've been running one kind of business or another for almost 20 years. I've dealt with lots of businesses, both as business person and as unknown consumer. In all that time, the only person who I know intentionally tried to cheat me, was an employee of a large department store.
But, perhaps that's partly because I always try to assume the best of other people. Whether I'm dealing with one of my associates, another business person, or an unhappy customer, I always assume their motives are above reproach. I always assume that others intend, just as I do, what is best for all involved. Some would say that I'm naive. I would counter that after serving two years as a magistrate judge (as I have), and after running various newspapers for several years (as I have), one is usually cured of their naivete. Instead I believe a trusting approach affects my experience. The person on the other end is usually a lot more responsive when they sense that I trust and respect them.
So, I'm on my soapbox. I know it's "politically correct" to assume that businesses are, by definition, greedy and inhuman. But, I would urge you to remember that businesses are composed of individuals. Some of those individuals are, like me, children of the sixties who care a great deal about being of service to their customers. Some, like our readers, are business people, or developers, or engineers all people who are just trying to do the best they can. People make mistakes and their businesses make mistakes. Sometimes they compound one mistake with another. All that proves is their human frailty. Thus I always make it a point to question only the mistake not the motives.
That's my belief. That's my company's belief. Business would certainly be easier and more rewarding if others acted out of the same belief. Thus, I beg my readers, next time you contact a business about a mistake, question the mistake, not their motives even if they compound one mistake with another.
Again, Paul, I'm embarrassed and dismayed by our response. I hope you'll accept my sincere apology for any inconvenience or grief we may have caused. rlw
Dear editor:
The enclosed disk contains proposals for enhancements to the C programming language to be considered by the ANSI X3J11 committee. (The contents of the disk are available with the supplemental code disk for this issue.) Here is a thumbnail synopsis of each proposal.
C-PACKED.TXT
I consider this the most important of the proposals. It deals with adding a packed decimal (integer) data type to the language. I consider this an important goal to meet if C is to make any impact on the business computing world.
Currently, the best we can get for numerical computations is 32-bit long ints, which are insufficient for meaningful dollar amounts, having a range up to only +21,474,836.47. Doubleprecision floating-point gives us around 52 bits, but the computations are an order of magnitude slower and least significant bits are too easily lost.
Adding a packed decimal data type, especially a long packed integer type of at least 15 digits, would be appealing for business computations, since it extends the range of integers substantially (up to +9,999,999,999,999.99 dollars).
Most of the issues involved in adding a new arithmetic type are addressed in the document, but a few (surrounded by brackets) still need to be ironed out. Also, the "usual arithmetic promotions" rules still need some work so they don't end up being pages, instead of lines, in length.
C-MESSAG.TXT
This is a feature that I've wanted, due to the nature of the business where I work. We port our UNIX/C software, unchanged, to a dozen or so platforms, each of which having its own quirks, bugs, and extensions. A #message directive would make porting an easier task, since the people doing the port to new and existing machines often have little clue as to what we, the developers, have done.
C-FUNC.TXT
This feature is useful for debugging. How many times have you and others you know reinvented a macro package for debugging that looked something like:
int func(a) int a; { int x, y; dbg_enter ("func"); ... dbg("a=%d, x is now %d", a, x); ... dbg_leave(); return y; }In this fragment, the dbg_enter and dbg_leave functions/macros keep track of the current function nesting level and their names, while dbg is used like printf. Some of this work is tedious, especially remembering to add dbg_enter and dbg_leave calls to every function entry and exit point. A __FUNC__ macro would make things a little easier.Ideally, what I really want are functions that are called every time a function is entered and exited, such as:
void func_enter(const char *name); void func_leave();This could be done by an implementation class in C++, where func_enter is a constructor and func_leave is a destructor for an object representing function tracing information. Alas, it is C and not C++ that we are discussing.David R Tribble
You offer several improvements that have been suggested in the past, in one form or the other. Unfortunately, right now the C standards committee WG14 has only a limited charter to extend the language. I expect the review process to begin sometime in 1995, at which point additions to the language can be again entertained. Keep reading these pages to find out the latest status of C and C++ standardization efforts. pjp
Dear pjp,
Ref: A Safer setjmp in C++, (C Users Journal, January 1993)
I quote two sentences from the article:
"If control has left the function that called setjmp, longjmp will usually crash" (the second sentence in the article)
"This technique isn't foolproof. It can still fail..." (the first sentence under heading "Limitations" towards the end of the article).
I skip the story, which can be found in between those two quotations.
Not so long ago (perhaps ten years or so), when C was nothing but a character in the alphabet, I sold my first commercial program, which was written in ... BASIC. The main function had a label error. As soon as an error condition was encountered, which the corresponding routine couldn't handle, control returned to error, where all motors were turned off, all files closed....and the stack pointer was set back to zero. The program was bombproof.
In the meantime, I have turned over a few million dollars in the software field (with the help of a few colleagues) and you are telling me, that there is no foolproof error handling in C, other than passing the control up the chain of nested function calls. The article mentions Borland "non-standard" methods, but fails to say, whether those methods are foolproof.
All I know is that Turbo C 2.0 is knowledgeable about a stack pointer. I don't know about Borland C++. What if you simply remember the stack pointer in main, and restore the stack pointer on an error condition, which cannot be handled by lower-level functions?
There are a few questions which are implicitly thrown up by the article: (so I dare to make them explicit here)
1) If the C Standard includes a setjmp and a longjmp, is it true that it is impossible to implement them? Or do compiler manufacturers simply not try hard enough?
2) Is it that the standards committee never paid attention to the question whether their "ideal" was possible to implement?
I must say, I did consult your Standand C book which I turn to as the most authoritative book in the matter. (Thanks for a book well written). But it fails to mention the problems raised in the article. I understand that if control is passed to a caller of the function, in which the call to setjmp() appears... there is no help... but just what does the above-quoted "If control has left the function that called setjmp" mean? In any callee of the function in question we should be fine! So let's call setjmp in main and we are fine! Because main has no caller!
Hasn't anyone ever implemented the standard? What is all this about? Have you been converted to C++? (The heading of the article seems to suggest that the answer is: use C++.) But then again the suggested solution isn't foolproof? Even in C++. I must admit the article left me 100 percent confused. Can you help me in this?
I always wanted to ask you: Where can I find the C Standard? Who sells it? (I can pay with a Visa account number or a cheque drawn on a US bank). I appreciate your journal (I just renewed my subscription for another three years) and I appreciate your book Standard C, but just where do I find the publisher of the C Standard. Let's say, I want to implement a C compiler: now whoever wants to sue me saying that I didn't implement the standard, what book/brochure does he hold against me? Perhaps the author of your article simply fell victim to someone who didn't implement the standard?
P.S.: Do you know about anyone who does all his programming in C++? I don't. Not in Europe. Windows is written in C (not C++). Everyone seems to write code in C, but then seems to write articles and publish ads on C++. I work for some 20 companies, but haven't found anyone who uses (uses!) C++. I haven't found anyone who used Prolog (when it was fashionable to use Prolog), nor have I found anyone who used AI (when it was fashionable to do so), nor have I found anyone who used CASE (when it was fashionable to do so). Is selling software nowadays just like selling clothes (keyword "fashion"). What is all this about? Did your advertisers convince you: better follow the C++ trend or else... We are all trying to make products obsolete by the magic of "fashion." Sellers unite! Caveat emptor. Your conversion to C++ seems to be somewhat faked. Who converted you? C++ is a bureaucrat's dream and a programmer's nightmare. And impossible to implement, going by your article. Neither C nor C++ provide for safe error handling. Come on! Tell me which language does and I will stop reading your magazine.
Sincerely yours
L. Engbert
Engbert UB
Taunusstrasse 8
D-6384 Schmitten 1
GermanyWow, you seem a little upset. I am answering these letters while on the road, so I can't reread the article you mentioned. I thought it simply warned about the known dangers of undisciplined use of setjmp/longjmp. A disciplined use, on the other hand, forms the solid basis for exception handling and error recovery in oodles of working code out there in the world.
I was an active member of X3J11 when it hammered out the specifications of setjmp/longjmp. I have also implemented these functions commercially on at least half a dozen different computer architectures. I assure you they are reasonably thought out and they work.
The BASIC error recovery you describe sounds like a yeoman attempt to retain control in the teeth of bad program errors. I and others often do the same thing in the C startup code, particularly for freestanding or embedded applications. It doesn't always rescue you, however. Curdling the stack can lead to too many kinds of craziness to assure that. Still, it's often worth a try.
You can order the C Standard from ANSI, 11 West 42nd Street, New York NY 10036, USA. Call +1-212-642-4900 or fax +1-212-302-1286. You will find it rather expensive. (I paid at least $140 a few months ago.) ISO in Geneva also sells the same standard. The address is at the front of my book, The Standard C Library, but I don't have it with me. DIN should also sell it in Germany.
Yes, there really are C++ programmers out there. I am currently attending the WG21/X3J16 meeting working on the C++ Standard. Hence, I am surrounded by C++ enthusiasts. Many others in the world are what we Americans call "tire kickers" (as when you inspect a car you think you might buy). But the number of serious C++ programmers is significant and growing. It is an inevitable artifact of journalism that we magazine editors focus more on what's new and developing than what's tried and true. So the mix of articles in this or any other trade magazine is seldom representative of what's actually happening in the world. We're not trying to distort reality, just give our readers what they need to know. pjp
Dear William,
Regarding William Smith, "An Essential String Function Library," CUJ, Jan. 1993:
I read your article with much interest in The C Users Journal. I am in the awkward stage of learning C and C++ so I can covert an application from Pascal to C, which is obviously the future, for which I can make good use of your string functions. I am now working with THINK C for the Mac, but I assume that if I can understand your code, I can port it to THINK C, but for this I do need some help, if you would be so kind.
For Example:
1. Your function str_insert(Str, Pos,Insrt) is comparable to the Pascal procedure insert(Insrt,Str, pos); {using your notation} but you cast Pos as a Char*, rather than an integer-type value as in Pascal. How does this work? I have not been able to make it function correctly in my test runs in C. Perhaps you could show me an example as your article assumes a higher understanding of C than I have at this time have. More annotating would have helped us C neophytes.
2. You use two functions in your code, main & max that are not include in THINK C libraries. What do these function do and where may I find examples of them?
3. Your function str_ljust is quite a bit different than one a have written called spacepad:
/************** SpacePad ************ * routine to left pad a string with * spaces * If str s is no longer * than len, it is shortened to len * It also returns original len of * s, if wanted************************************/
short SpacePad(char *s,short len) { short i; i = strlen(s); /* start pad/cut routine */ while(i < len) s[i++] = "; /* pad s to len */ s[len] = '\0'; return i; /* returns len of s */ }I must assume that yours handles memory better and is less inclined to cause crashes? True? False?I am enclosing a self addressed envelope for your reply, if you could find time to do so.
Sincerely yours,
Arne Bystrom
1617 Post Alley
Seattle WA 98101William Smith replies:
1) Pos is a pointer to a location within str. Pos in pointer form is equivalent to: Str + Pos if Pos is an integer index or &str [Pos].
2) min and max are macros defined in the include file stdlib.h (Microsoft c).
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b))3) Not necessarily true. They are functionally equivalent, and just represent different ways to do the same thing.Dear Dr. Plauger:
Elaboration on the pros/cons of using #define's vs. const for string ID's, help contexts, etc., in both C and C++, would be appreciated.
Also, more coverage of the Borland app. Frameworks (esp. Turbo Vision for C++) would be welcomed!
Thanks for an ongoing fine job.
Sincerely,
Bryan D. Feldman, President
Service Ware International
2376 Arrow Circle
Atlanta, GA 30341Thanks for the feedback. pjp