Letters to the editor may be sent via email to cujed@mfi.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 Mr. Plauger,
FYI, the United States anonymous ftp site for the OSE library is now:ftp.odi.com [198.3.16.26] directory pub/OSEas specified in the FAQINFO document, which can be downloaded from the European site:
ftp.th-darmstadt.de [130.83.55.75] directory pub/programming/languages/ \
C++/class-libraries/OSEor the Australian site:
cbr.dit.csiro.au [192.41.146.1] directory pub/SEG/oseI hope this saves the next person the trouble I went to to find the library.
Regards,
Dale E. Muir
CUJ,
RE: Letter from L.J. Sellers, March 1996 (ok, so I'm a little behind). pjp states, "In my 90 or so years of preaching ...'' No way is P.J. Plauger 90+ years old! (The + is just assuming there was some gestation period somewhere; maybe not!) Of course 90 years could imply some sort of parallelism; I do learn twice as much from P.J. as from anyone else. This still puts his start back in the early fifties. Wasn't Fortran invented in the fifties? Musta been coding assembly. Or better yet, those little toggle switches. Object Oriented Toggle Switches (OOTS, pronounced "oats'').
Mr. Sellars (apropos?) started way back in 1936! Wow! Maybe he was coding the Enigma (Sellars could be German). My ealiest CUJ is from the 80s. If I'd known you've been publishing since the 20s, I would have had my grandmother subscribe for me. My stars!
Bill (upstart: only twenty years of coding) Sutphin
Well, I did learn Fortran as my first programming language, and I have programmed via toggle switches, but I'm not really quite that old. I was merely continuing the escalating hyperbole of the letter to which I was responding. -- pjp
Editor,
I have been tasked with attempting to locate another copy of a lost shareware library called gui.lib, which was used to produce a program that ran in DOS and contained C++ functions. Have you ever heard of this or have any ideas as to where I might be able to locate it?
Fortunately this file was lost before I came onboard and started formal backup procedures. Need I say more. Unfortunately, it is now my problem. :(
Sincerely,
David C. Keith
Naval Health Research CenterAnybody? -- pjp
Editor,
Would somebody with more influence than mine please lobby the C++ standards group to add template member functions to a non-template class! Here's what we'd like to be able to do:
class foo { public: template <class T> void Bar(T t); };Now I could write code as follows:
foo f; f.Bar(i); // i is an integer f.Bar(f); // f is a float f.Bar(varSomeType); //etcThis turns out to be incredibly useful. Right now we use a template function as a workaround:
template <class T> void Bar(T t, const foo & f);It seems rather silly that the latter is available within the standard and the former isn't.
David Jameson
All I know is, the implementors seem to be having problems enough implementing member templates within templates. Still, your request has now seen the light of day, at least. -- pjp
Editor,
Where can one of us mere mortals find the complete ANSI Standard for C? When ANSI/ISO finishes with C++ will that document be available to the general (interested) public? Dan Saks's column in the May issue got me to thinking about how little I've paid attention to the grammar of either language, and I thought that the standards should be the place to start getting back to those basics. Can you help?
Glenn Porter
You can purchase the C Standard from ANSI in New York City, but you can get it much cheaper by buying Herb Schildt's The Annotated ANSI C Standard, from Addison-Wesley. The publication of standards is a topic of ongoing debate these days, so it's hard to say what your options will be when the C++ Standard settles down. You can be sure that it will be available in one or more forms, however. -- pjp
Editor,
I don't think I've seen this question addressed yet, sorry if it's already been answered.
Why doesn't C++ have an operator such as "immediate ancestor?'' For example, if class C is derived from class A and needs to call a method from A, why must one use A::foo() instead of something like ..foo()? As you can see, this is quite different from the global resolution ::foo().
I have thought this to be a useful device since learning C++ in the late 1980s, but now that various wizards (such as those provided with MSVC and Borland among others) create derived classes from simple ``cookbook'' templates, it seems a fair number of errors are introduced if one needs to implement a class between the derived class and its parent.
The common error I have seen lately is from CDialog. It is very convenient to derive from CDialog, but then change the parent from CDialog to something like CMyDialog. Unfortunately, this necessitates doing a search and replace on the new header and source files, while a simple immediate ancestor operator would allow one to insert any number of layers by simply changing a single reference in the class definition.
Thanks for your time,
Kyle YorkA member class has no special access privileges to its containing class. You have to declare it a friend of the containing class to peer inside. Tempting as it is to model access hierarchy after file systems, you may find it of limited usefulness in the end. -- pjp
Dear Mr. Plauger,
In the function _Stoul in Figure 13.12, p. 360, of your book The Standard C Library, shouldn't 0 also be a silly base? That is, why not replace the line:
if(base < 0 || base == 1 || BASE_MAX < base)with:
if(base <= 1 || BASE_MAX < base)The following program:
#include <stdlib.h> int main(int argc, char** argv) { long i; i = strtol("0111001", 0, 0); printf("i = %ld\n"); return 1; }prints i = -2147483647 on a Sun and i = 37377 on an HP.
Sincerely,
Jim WardA base of zero has special meaning for the overlying strtol function. It tells the function to determine the actual base by the same rules as for numeric literals in C source code. In your example, the base should be taken as 8. Looks to me like the Sun version is in error. -- pjp
Hello,
I have a small problem understanding a piece of code in the MFC library, which is a C++ issue. I have asked this question to all the C++ experts in my company, and some of the C++ Q&A columnists as well, but no one seems to be able to help me. Could you please help me out.
I was looking through the MFC TRACE expansions, when I came across the TRACE0 macro expansion. In the debug mode, it expands to (afx.h):
#define TRACE0(sz) \ do { \ static char BASED_DEBUG _sz[] = sz; \ ::AfxTrace (_sz); \ } while (0)Now, my question is this: Why should there be a do-while out there. My guess is that it has to do with scoping of _sz. But if it were that, just using {} would have solved the scoping problem, right?
Looking forward to hearing from you. Thanks in advance,
Raja
raja@imagine.uunet.inIt's an old trick, but nevertheless one that is not widely known. The do-while lets you write the macro invocation as if it were an expression statement, complete with trailing semicolon. The brace-enclosed form doesn't always bind properly with that trailing semicolon, particularly in the middle of an if-else statement. -- pjp
Dear pjp,
I fell down laughing when I read your editorial this month (February `96). I know what you mean; I reinstalled the old Dos/Wfw last december -- I was just fed up with pressing F8 every boot. But then, I'm just a newbie in computing (well, relatively). Hearing that from you has been great!
Anyway, even if I don't happen to be an old friend of yours, I feel like asking what's wrong with you. Nostalgia?
95 hasn't brought a good vintage, So what? Even my favorite wine was not good, because the rain has been too much. 96 will be better...
And the weather is more complex than Windoze 95.
Keep up the great job.
Alessandro Vesely
Dear CUJ:
My wife Diana is learning C++. She wrote the exercise shown in Listing 1 first using iostream.h. The program did not execute as expected at first. The first pass through the do-while loop worked OK, but on the second pass the cin.get() seemed to read data left over in the buffer, probably a '\n', and so the str array remained empty. The same behavior is seen when compiled for stdio.h. Adding the fflush for stdin fixed the problem behavior.
After perusing various references for iostream.h, we found the ignore() member function. Calling ignore() defaults to ignoring one character, which in our case did the trick. We still don't know how to flush all the input from cin. There is no flush() member function, like there is for ostream.
Two questions. First, we expected the program to work without any flush calls. Why are they needed? Second, more broadly, iostreams seem harder to use than stdio. Yes, they provide type safety, and the ability to read and write objects to streams. But the learning curve is steep. Why isn't the correspondence with the functions in stdio a little better?
We hope some readers will find this an interesting question.
Thanks,
Richard and Diana BrewsterYou raise several issues here. First, the member function get you are using does not consume the terminating newline, while the C function gets does. In either case, however, you proceed to read a single character in reply to your prompt. A much better style is to read an entire line, including the terminating newline, to consume any reply to a prompt.
As you discovered, the member function ignore does indeed consume a single character. But you lucked out in C. The use of fflush to discard input is a nonportable extension rooted in the early days of UNIX. It does not necessarily do what you want on all systems. And that's why class istream has no member function flush -- there's no way to implement it portably atop a Standard C library.
Put simply, neither version of your small program is completely bug free or robust. Each needs a bit of tweaking. -- pjp
Dear Editor:
I have just finished reading Kenneth Van Camp's article "A Template-Based Quicksort,'' in the March 1996 Issue. I found the article informative, but the quicksort template presented was somewhat limited. I am involved in developing large systems and I am continually faced with the task of sorting the same collection of objects based on different data members. The quicksort template and most sorted collection classes I have seen do not easily accommodate this; however, the function pointer based approach of qsort handles it quite well. Therefore, I would propose creation of a double template based on both the data and a key. The following header shows the signature of the proposed templates:
//newqsort.h #ifdef NEWQSORT_H #define NEWQSORT_H template< class T, class K> void qsortVT(T *data, K *key,const int num); template< class T, class K> void qsortPT(T **data, K *key, const int num); #endifThis new function sorts the data using the associated key values. The > and < operators can be defined differently for each key type. This has the benefit that the same set of data can be sorted differently simply by providing an alternate list of keys. Comparison of individual fields of an object is more intuitive than defining > and < operators for the aggregate objects, since multiple orderings of objects are possible.
For example, an object representing a person could be ordered by last name in one section of a program and by age or income in another section. Although I have not seen the proposed Standard Template Library, I hope that it will contain template based sorting functions and sorted containers that allow objects to be sorted based on different data members.
Sincerely,
Michael E. Martinka
mmartinka@aol.comSTL indeed has that flexibility. -- pjp
Editor,
Long Long Ago, when CUJ was literally a newspaper, you published a few articles on C under HDOS! Are these still available? Is the source code available for downloading? With my Linux system around my house and and my SPARC2000/GIG-O-Memory I still long to program my old H8. It was fun!
Gene Brandt
Yeah, I built one of those H8 systems myself. I didn't much enjoy it until I wrote a C compiler that would run on it, however. If that code isn't captured on an early CUG diskette, it's probably gone for good. -- pjp
[Actually, the CUG Library includes a volume you might find very useful: the Micro-C compiler, CUG #422. According to its description on the CUG web page (http://www.hal9k.com/cug/), "Micro-C is a tiny compiler which can run with less than 32K RAM and yet is highly independent of CPU and OS." You can get the CUG Library on CD-ROM (some 300+ volumes of source code) for $49.95 plus $3.50 shipping and handling. e-mail rdorders@mfi.com, or call 800-444-4881. mb]
Code Update
When we uploaded the code for Don Colner's "HTML Programming with Objects," (CUJ, July 1996) to our ftp site, we split one of the files (strclass.h) incorrectly. We have since uploaded a corrected version to the ftp site and updated the July code disk.
Also, those of you who downloaded the August code early, we have recently added a lot of material to dwyer.zip. You may want to revisit the site. mb