Departments


We Have Mail


Dear Mr. Ward,

I felt that some of the points raised by Phil Cogar in the letter published in the Jan. '90 issue deserved a response, although I don't know whether such a response fits within the subject range of your magazine.

Evidently, there is a market for language translation tools, at least three of which are advertised in this issue at relatively reasonable prices. I hope to get an opportunity to try some of them myself.

Rex Jaeschke has pointed out that C may not be the most cost-effective language for development or maintenance of software which fits the design of other languages, such as Fortran. Assuming that one has decided to use software developed in another language as part of a system written in C, several courses of action are available. These might include translating once and discarding the original, modifying the original to the extent necessary to maintain satisfactory parallel versions in two languages, or building a system in more than one source language. Any combination of these methods might be valid, and either of the first two would benefit from translation tools.

Considering the difficulties of translation and the undesirable practices found in most freely available code, no translator can pretend to be able to generate bug-free code. It is usually easier to compile the code in the original language and verify operation with a few test cases, and maybe even clean it up and retest it before translating.

One of the problems with a multi-language system is that the interfaces between languages are not always satisfactory, never covered by any nonproprietary standard, and unlikely to be subject to any of the usual safety checks, such as lint. This often leads to errors, like my forgetting that I was writing about a matrix set up by C rather than one set up by Fortran.

A compromise which often works well is to choose one language as the primary one, with only low-level functions with simple calling interfaces written in the other language. This may be no more than a minor extension of the way the language system is actually written, as in the case of a Fortran runtime library much of which is written in C.

On many modern systems, the C compiler has received the most attention of the various languages, and it may generate more efficient code. In particular, the amount of code required to set up loops seems to be consistently less in C, and operations such as those required in searches and sorts are unlikely to be optimized in early versions of compilers for other languages.

For some examples which do not particularly favor C, we may look at some old Fortran coded problems. On the Multiflow Trace computer, 22 of the 24 Livermore loops run up to 10% faster in C than in Fortran, with the other two running much faster in Fortran only through the use of compiler directives (pragma) or in-line compilation of math functions. The Sun 4.0 C compiler is able to compile linear searches through floating point arrays with code which runs 40% faster than under their optional Fortran.

For those who wish to know what axes I am trying to grind, I am on the verge of embarking on a project to support the SLATEC mathematical library in C and Fortran in a way which should suit the needs of those who need source code at a fair price to run on a variety of platforms. If we don't get approval from the owners of the rights, we will be looking for alternatives. I am working also on a series of hands-on learning seminars which will likely be presented in 6 hour increments, beginning with application performance tuning for pipelined architectures in C and Fortran, and UNIX familiarization for Fortran programmers. All in addition to my job in aerodynamics design and computation.

Tim Prince
39 Harbor Hill
Grosse Pte Fms, MI 48236

Just for your peace of mind, you are not alone. Researchers in the Advanced Computational Resources Lab (I think I have the name almost right) at Argonne National Labs are also interested in persuading scientists to develop numerical applications in C — in part because the most advanced parallel hosts are first programmable in C. You might find their book Portable Programs For Parallel Processors interesting (Boyle, Butler, et. al.). —rlw

Dear Mr. Ward,

I have my problems with recommending The Awk Programming Language by Aho, Kernighan and Weinberger. It is an excellent reference to Awk, but is confusing when one is working with the older versions (older than System V v3.1). It brought tears of frustration until I happened to do a

tail /usr/bin/awk |od -c
and came up with "(Berkeley) 9/16/83.". Clearly, an early version.

There is a very good simpler explanation of awk in the chapter "The Awk Power Play" in UNIX Papers for System Developers and Power Users by the Waite Group, Howard W. Sams & Co. Learning regular expressions at the awk level is best as the regular expressions of "sed, grep, egrep, and fgrep" are subsets of this.

One cannot be sure exactly what Dr. Whitaker is trying to do, but I have found that awk is ideal for extracting ASCII information from tables and that little language is all that he might need.

UNIX tools are in a sense all "little languages" and this can explain their lack of coverage in the literature. I doubt if an author could convince his publisher that it would pay to cover these. So one must find information wherever he can; appendices, mixed in with other coverages and "between the lines." I have found that Howard W. Sams and The Waite Group are excellent in their coverage of "UNIX-oriented tools". Advanced UNIX — A Programmer's Guide has an appendix on UNIX tools; other recommended are UNIX System V Bible, Tricks of the UNIX Masters, and The UNIX Shell Programming Language give innumerable examples.

Personally, I enjoy using UNIX tools in developing applications and turn to the C language to do whatever I cannot accomplish otherwise. In other words using other people's ideas before reinventing the wheel. However if somebody can tell me how to document such a mixture, I would appreciate it.

Yours sincerely,

Alan E. Ternstrom
5321 Perkins Rd. #122
Oxnard, CA 93033

The UNIX tools are undeniably neat; I just developed a full-function mailing list package for my wife in about 30 lines of shell script (with about six four- or five-line awk scripts). Unfortunately, documentation is only half the problem. We're finding that since programmers must master six or seven fairly complex and independent syntaxes that developing skilled maintenance programmers for mixed tool applications is especially difficult — the increased "bump" at the beginning of the learning curve can easily frustrate a newcomer. Anyone have some suggestions? —rlw

Dear Editor:

I would like to ask you to look at the opening two paragraphs of the Doctor C's Pointers in the February issue.

I like the first paragraph. It matches my experience: Try a few things to see if the concept will work and then, because of lack of time, build the rest of the program in a stepwise fashion. It prepares me for what I would consider an excellent article: How to pull hard coded definitions out of a program into headers.

The second paragraph is in total opposition: "Headers must be done before any code is written."

In fact, the article is rather good in its information while having almost nothing to do with either paragraph. It certainly does not assist people working per paragraph one, while not being as rigid as paragraph two.

I think the editor needed to do some editing here.

The article "Tools For MS-DOS Directory Navigation" by Leor Zolman contains at least one serious error and a couple of misapprehensions.

The serious error is "there is no facility for viewing all active assignments" with SUBST. This is simply wrong. Typing SUBST with nothing after it instantly lists all current substitutions. I use it constantly.

The primary misapprehension is that it is desirable to change default drive when CD is used. About half the time, I would then have to change back to my original default. I get the feeling that Zolman works in an environment where CD supports only one directory at a time (Apple ProDOS does this, maybe UNIX does also), not the one per drive that MS-DOS provides.

While his choices are interesting, I am not sure a C program is needed, since most of what he does can be done with a batch file in far fewer lines. I can do his previous in the rather stable environment I work in most of the time by using SUBST to simply create a new drive. I typically have 8 or 10 "drives" specified on my system (118 directories.)

Mike Firth
1019 Martinique
Dallas, TX 75223

Leor responds:

Yes, typing "subst" by itself does indeed display all active assignments. The DOS manual for my system didn't happen to mention that little feature. I still dislike "subst" for several reasons, however:

1. After selecting a virtual drive defined via "subst", there are two different notations for specifying the full pathname of any file on the virtual drive (one using the "real" drive, one using the virtual drive) but no way to access those portions of the file tree that reside "above" the base of the virtual drive without reverting to "real" drive notation. This leaves "subst" looking adequate to specify data paths for applications programs, but not too intuitive for general-purpose file system navigation.

2. After a virtual drive has been assigned with "subst", any redefinition of that drive is prohibited by DOS. This makes the implementation of a generalized "return to last directory" mechanism using "subst" seem impossible (at least if you want it to be able to work more than once.)

3. Finally, to be able to use "subst" at all, CONFIG.SYS must be changed and the system re-booted.

Regarding my alleged "misapprehensions", please realize "cde" and "ret" are meant to work in conjunction with the built-in "cd", not necessarily as absolute replacements for it... "cd" may still be used anytime to change any drive's default directory without disturbing the operation of cde/ret.

The philosophy behind cde/ret is simply to reduce the number of keystrokes needed to move between directories, and to make DOS behave a little bit more like UNIX; whether or not that is better, of course, boils down to a matter of personal preference.

Dear Mr. Ward:

I would like to advise CUJ readers of a potential problem that may occur when using Turbo C's integrated environment. I encountered this problem when I combined completed modules of the system I worked on into one library. I used the TLIB utility, and the resulting file was named CHELIBS.LIB. But after I replaced numerous C-source and OBJect file names in the PRJ file with CHELIB.LIB, I encountered a surprising reaction: my Turbo C integrated environment (v2.0, tc.exe dated 8-29-88) failed to link the executable file due to numerous unresolved external references (_setargv, _setenvp, and _exit, among others).

After careful study, I learned that this error occured due to a bug in Turbo C. Turbo C does not correctly handle LIB file names listed in the project file. My library's name began with "CH" (like CH.LIB, Borland International's library of huge memory models), and this file was interpreted by Turbo C as its own library. Hence, CS.LIB (I used a small memory model) was not linked at all. When I renamed my library to LIBCHES.LIB, all was well.

My research has shown me that users' libraries can't use titles beginning with any of Borland's library names (i.e., CS..., CM..., CC..., CL..., or CH...).

I hope my report will be useful to Turbo C users, and I am happy to make a contribution to CUJ, however small it may be.

Sincerely,

Alexander Vladimirovich Pavlov
Poste restante,
Central Telegraph Office
Moscow K-9
103009 USSR

Thanks for the information. It's neat to get letters from the USSR. —rlw

Dear CUJ,

Simon Wheaton-Smith's letter (February 1990 CUJ) deserves patience and a response. While his tone is fanatical, even fanatics have been known to have insights.

I have found the C source code he placed on Compuserve (GO CLMFORUM, in the OOP Alley library as OBJECT.C). In this example, he demonstrates that it doesn't require extensions to C or a new language to provide encapsulation, dynamic allocation or to place panels and buttons on the screen. I hope we're ready to agree that these characteristics are not unique to object-oriented programming.

There are additional features of C++ which Simon admits are absent from C but which Simon suggests are best provided by a more robust preprocessor. These features are overloaded functions and inheritance. One could argue that, in fact, C++ is just such a preprocessor. Or, one could argue that Simon is suggesting a new language, since a preprocessor can be considered a language. We might call this language "C with overloaded functions and inheritance" instead of C++ (formerly known as "C with objects").

I would argue against preprocessors in general. If Simon has developed in C for MVS environments, then he is probably familiar with the C compiler IBM has been marketing. I believe this product is still a preprocessor, producing assembler code. C's limited I/O features have not been extended to match IBM's access methods and so, more often than not, the assembler code is doctored to produce the desired application. The original C code ends up being discarded and you're developing an assembler application. As you would expect, there's not much serious C development on MVS environments. (This situation should eventually change now that IBM has endorsed C as one of the four SAA languages, as Simon points out.)

This is the danger with preprocessors. Just as with C macros, only the simplest of functions belong in preprocessor macros.

I am not particularly a fan of C + +. I agree with Simon, that C + + is "a random collection of items". I've been pleased with its cautious reception. But C + + does have a certain amount of promise — given C + + and a robust class library, we should be able to quickly produce terse programs.

This seems to be what we want from a development environment, and the direction that modern languages should take — rapid development in a brief and clear style that produces efficient code. The language should be suitable for group development. We want mechanisms which encourage (perhaps enforce) reusable code design — it's difficult to say that software can currently be characterized in "generations". It remains to be seen if C++ can deliver on these promises.

A note on efficiency — Simon would lead us to believe that the programmer is responsible for optimization. I, on the other hand, believe this to be a cooperative effort between the programmer and his compiler. When we have a language which permits a programmer to briefly and clearly describe what needs to be done and a compiler which determines the efficient way to get it done, we'll have a development environment we can stay with for a while.

Russ Klanke
6840 Oswego Place NE #306
Seattle, WA 98115

Thanks for writing such a reasonable response.

Personally I don't agree that C++ is a random collection of items. I was fortunate enough to sit in on a two-day C++ seminar by Bjarne Stroustrup a couple of years ago. I was impressed with his justification and rationale for the features included in C++. I think he's done a remarkable job of adapting language features invented in a "protect the programmer from himself" environment so that they fit reasonably in C's "you'd better know what you're doing" world. rlw

Dear Mr. Ward:

When I was a child it was rather common to hear from one of your playmates(?) the taunt "I know something you don't know." I am surprised to find it continued in The C Users Journal in Mr. Brannigan's article on "Fitting Curves to Data".

Mr. Brannigan states: "It is not difficult, for example, to input data for a linear regression routine to a well known statistical package (which I shall not name) used on micros and mainframes for which the output is incorrect."

Either name the offender or do not make the accusation. In the context I am familiar with professionally, if you disagree with something that has been claimed, you state your disagreement and give supporting evidence for that disagreement but you do not make the type of accusation Mr. Brannigan has. In my opinion Mr. Brannigan has by such behavior damaged only his credibility.

Sincerely,

Morton F. Kaplon
1047 Johnston Dr.
Bethlehem, PA 18017

When I edited that story, I almost deleted the parenthetical remark to which you refer, just because it wasn't really necessary. Perhaps I should have.

Had I read it as you did, I certainly would have deleted it. For me, as a small publisher, I brought other assumptions to the table. I figured Brannigan was just trying to spare me the wrath of some major software vendor. Had he named the vendor, I would have been forced to verify the error before publication or run the risk of being without defense against a potential libel suite. Since the error itself wasn't critical to the story, I would probably have deleted the comment instead of investing resources in doing "quality control" for a product of minimal interest to my readers. Which is better, having readers be placed on notice (albeit vague notice), or saying nothing at all? rlw

Re: Passing and Returning Objects in C++

In his article in the August, 1989, issue, Bruce Eckel gives an interesting description on how values are passed to C++ functions. Unfortunately, he makes a few errors which detract from his presentation.

First, he incorrectly describes passing arguments to a function by name. He states that this is when a pointer is passed to a function. In fact, passing an argument by name uses Algol's copy rule: the entire text of an argument is reevaluated each time the name appears in the called function. This somewhat resembles how arguments to C macros are handled.

C does not have call-by-name or call-by-reference. In C, only values are passed. When a pointer is passed, it is passed by value. The programmer must account for the fact that a pointer value is needed when the function is called and that the value of the argument received is a pointer. This means that an expression that is not an lvalue cannot be used as an argument for a function expecting a pointer value.

C++ did extend C to add call-by-reference (but not call-by-name). While this is most often implemented by passing a pointer to the function, it is not the same. The programmer need not know whether a function is called by reference or value: the call is the same and the argument need not be an lvalue.

He makes another error in stating that structure assignment is limited. The example he uses

A=B=C;
works in ANSI C both for simple data types (int, float, etc.) and for structures.

He also describes a method of returning a structure which can only be used when the called function is not recursive. When the function is recursive, space for the returned value of the structure is usually allocated from a stack. Implementations of C++ can use this same method of returning objects. Both C and C++ are free to pass "hidden" addresses for a return value, as Mr. Eckel describes for C++.

Inaccuracies like these in describing C cast undeserved doubt on the remainder of the article.

Sincerely,

Michael J. Eager
Eager Consulting
481 Century Dr.
Campbell, CA 95OO8

The readers will have to judge this dispute I don't know enough about C++ to make a call. For the record, we did have Eckles' article reviewed by a second competent C++ programmer before using it. So, there are at least two programmers in at least one other environment who have a different understanding. Perhaps someone can explain why the confusion? rlw