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 PJP,
Re: Lee Stewart (July 1997) and Vince Pachiano (March 1997) on character-set design origins. My background was ICL and DEC machines in the 1970s, using DEC and IBM 026 and 029 card punches, and TeleType ASR 33 and 35 terminals cum paper tape reader/punches; IBM mainframes and 3270 terminals in the 1980s; Unix boxes and character windows in the 1990s (could have saved myself some time and bother by starting out right!).
From my memories of reading device-driver code, I believe that both character sets arose for easy encoding from input devices: EBCDIC from punch cards and ASCII from TTY keyboards. IBM built machines having word lengths with multiples of four bits and used BCD/hexadecimal, whereas the BUNCH (Burroughs, Univac, NCR, CDC, Honeywell IBM's mainframe competition historical note for younger programmers!) and DEC machines originally had six-bit characters, with multiple characters per word, and used octal.
IBM favoured cards, and EBCDIC makes a lot of sense viewed as punch card codes in two BCD digits: 0-9 punches coded in the low nibble; and 10-12 punches, as shift codes, in the high nibble. The competition seem to have liked TTYs, and ASCII separates out the control, special, digits, and alpha characters nicely and the operation of the control and shift keys when shown in octal (taking into account the rat's nest of wiring required to alphabetize the codes from the QWERTY keyboard this may have been somewhat modularized, with groups of eight to 16 keys).
I am afraid time and migrations have taken their toll of any documentation or diagrams to illustrate these points, but you may have a better filing and retrieval system, or sources, than I, to remedy this.
Personally, I would like to thank you for your great writing (natural language and code), from the first two K&Ps (Elements and Tools) through Programming on Purpose to your "Library" books, and the other thoughtful articles (and humour) throughout that period, which have enlightened and encouraged me to continue programming and tackling all the problems that fleshing out the design is heir to, with better approaches to both man and "beast." Anything with PJP anywhere on it is worth buying to read (and me a Scot!) Ever consider selling monogrammed T-shirts?
Take care.
Thanks,
Brian Inglis
Brian_Inglis@CompuServe.com
binglis@nrginfo.comMy recollection of early card codes and ASCII pretty much matches yours. There was at one time some method to each flavor of madness, lost now that saving an occasional diode is no big deal. pjp
Dear Mr. Plauger,
First, thanks very much for the articles in C/C++ Users Journal. Since I am (finally) getting into STL, between your articles and Nelson's book, I've found lots of help. I've tried to keep the question below as brief as possible.
Nelson has an example for multiset in which he defines a custom operator for struct product (pg. 264). This, however, does not work for multimap. Here is a clip of my attempt:
// key struct SMsgGroup data typedef unsigned long MSGGROUP; { ........ <other elements> // priority order for nGroup element // I'm trying to use for "subordering" ULONG ulPriority; bool operator<(const SMsgGroup& _a) const {return ulPriority < _a.ulPriority;} }; typedef multimap<MSGGROUP, SMsgGroup, less<SMsgGroup> > CMsgGroupMap;I get an error at the internal class value_compare (specifically, the return line within the internal value_compare class). The compiler tells me: "cannot convert parameter 1 from 'const unsigned long' to 'const struct SMsgGroup &' "
Can the predicate less function be applied only to the key (rather than the data I'm storing with it, such as I've attempted)? Can a custom comparison be implemented, or is this something that multimap simply doesn't handle? (I can apply a workaround, such as multiple scans through identical keyed elements using the iterators.)
Thanks in advance for any help you may provide.
Dave Dozier
Rock Systems, Inc
ddozier@rock-systems.comYour problem is indeed an incorrect compare function. You need a function that compares only the keys. This is not a problem in set or multiset, where the key and the data are the same. pjp
Hi Mr. Plauger,
I was rereading the June 1997 issue of C/C++ Users Journal when I came upon your editorial asking for comments on Java. (Each time I study it I seem to reach a higher level of understanding, if that makes any sense to you.) Having some experience programming and being new to C++ and Java, I thought you might like a student's perspective (albeit a 50 year old student).
Java is quite a reasonable language compared to C++. As a student of C++, for instance, if I overload a function I am not always sure what code would call what functions. Is it what I wanted to do? I learned to live with it. But I spend a lot of time accomplishing little. I am not altogether sure that I am alone in this problem. This is just one minor but typical problem with C++ from my perspective. It is needlessly complex.
One misconception that you can allay is that Java is easy. Since it is strictly object oriented, there are a lot of tricks to learn to deal with that. You know them or are at least not seeing those sorts of things for the first time. Most students are. One other thing from a student's point of view, the incompatibility of different versions of Java drive me nuts (A short put). Although I understand the reason for it, just compiling the same program on different versions requires different paths in the autoexec batch file on my computer. C++ and Java both have steep and long learning curves for most people. I think Java is on the right path. Although it is not always backwards compatible, it may lead to a more useful language in the long run.
By the way the text that I find the most useful for Java is Peter van der Linden's Just Java. Like you he does not try to oversimplify on the one hand or show how smart he is by making it needlessly difficult on the other.
Keep up the good work and Thanks,
Tom Linehan
tjlinehan@worldnet.att.comI agree that Java is neither a simple language nor the ultimate in portability it is cracked up to be. I also agree that it's a pretty interesting addition to the C stable of languages. Glad you're having fun with it. pjp
Dear Mr.Tim Patterson,
There is a letter from you in the September 1997 issue of The C/C++ Users Journal. You wrote, "I have network-specific and standalone-specific dialogs, popups, menuitems, etc. in the resource script. I don't know how to edit the resource script or delimit my code in a way that the code generator won't modify or trip over my changes."
I think I have one solution to the problem.
MFC projects have an .rc (resource script) file and resource.h. You don't need to edit an .rc file to delimit code. You can do it with resource.h. In this way resources for both cases (network and standalone) will be linked in the resulting .exe file. The application will not need both of them, but since you use only common resources (dialogs, popoups, menuitems, etc.) they aren't too big. Imagine that you have one dialog box which is different for both cases. You'll have following lines in resource.h:
#define IDD_MY_DIALOG_NETWORK 100 #define IDD_MY_DIALOG_STANDALONE 101 #ifdef __NETWORK_RELEASE_ #define IDD_MY_DIALOGBOX \
IDD_MY_DIALOG_NETWORK #else #define IDD_MY_DIALOGBOX \
IDD_MY_DIALOG_STANDALONE #endifIDD_MY_DIALOG_NETWORK and IDD_MY_DIALOG_STANDALONE are generated by MSVC's Visual Studio when you create both dialog resources. When you need to create this dialog box just use IDD_MY_DIALOGBOX to invoke CDialog's constructor:
class CMyDialog : public CDialog { public: CMyDialog(); // Dialog Data //{{AFX_DATA(CMyDialog) enum { IDD = IDD_MY_DIALOGBOX }; //}}AFX_DATA .. ..... }; CMyDialog::CMyDialog() : CDialog(CMyDialog::IDD) { //{{AFX_DATA_INIT(CMyDialog) //}}AFX_DATA_INIT }You can use this technique when you use other kind of resources than dialogs.
Regards,
Stefan Tchekanov Plovdiv
Dear Sir,
Your magazine is valuable, informative, and sometimes entertaining.
You mentioned that you had a lot of trouble getting a driver out of your laptop. I expect you will get a lot of mail on this, but I'll relate my own similar experience anyway. From context, you seem to be running Windows 95 on the machine, not Windows NT. I've had similar problems with drivers, and other applications that load on startup with Windows 95, but I didn't have a second machine to shuttle data to, so I had to find the source of the problem. It was a "learning experience" :-).
The problem can be traced to the fact that Windows 95 is a transition from the older Windows 3.x operating system to something like Windows NT. The registry, which will eventually be the central repository for all system relevant information is not yet the only such repository. A lot of information, particularly startup information, is still kept in the system.ini and win.ini files. Junk can accumlate in these files as well as in the registry and the config.sys and autoexec.bat files. There is at least one other such repository that I have not found yet.
Interestingly, your opinion of Windows 95 mirrors my opinion of Unix. I came to Unix late, and find it almost as arcane as Windows. There are as many, if not more, different places to look for configuration information when you include the inumerable Unix variants as there are in Windows. I can only conclude that this kind of "rust" happens to all operating systems that have grown to the point where more than a small number of people have contributed to their development.
Max TenEyck Woodbury
mtew@cds.duke.eduI have indeed received lots of commentary and advice as a result of that editorial. In this case, I did know enough to check the older .ini files, but that wasn't the problem either. I've since had occasion to dig another Xircom driver out of yet another Windows95 laptop. Their customer support person led me through various arcane corners of the Registry to clean out the infection. Not easy. And yes, I agree that even good old Unix has also become work hardened from the application of too many hammers. pjp
Editor,
Howdy! I just got around to reading the latest issue of CUJ, and your Editor's Forum kind of worried me. To start with, I'm a newbie programmer (in the extreme). I've been using C++ for about eight months (coming from a background as a 3-D artist). Part of the fun of learning C++ was the feeling of being on the cutting edge of a continually evolving language. But, in the column, you say that the draft will be "really, really, honest to goodness, frozen." Now, forgive my complete ignorance about these kinds of things, but does this mean C++ will never, ever be updated again? Or, does it just mean that this particular revision of C++ is being finalized?
Thanks in advance! (And keep up the good work!)
Brenden Mecleary
bman2@ix.netcom.comC++ is still very much a work in progress. What the C++ Standard will do is offer a fixed point for commercial compilers and test suites to aim for. Companies that need stability will welcome a stable dialect of C++. Others will keep on tinkering. Not to worry. pjp
Mr. Plauger,
I've been reading a number of articles about the C++ draft, including yours, Dan Saks', and Al Stevens', and I'm concerned. It seems that the consortium has lost sight of their original objectives. I thought C++ was supposed to be an extension of C, not an entirely new language. From what I've been reading, a C programmer won't even be able to read a C++ program. What with the new namespace additions (::std for example) and other changes, C++ is beginning to look more and more like Ada, which I think was designed by committee.
One major concern I have is this ridiculous decision to remove the extension from header files. Why? The purpose of extensions is to provide a user with a hint of the purpose of the file (C source, Assembler source, WordPerfect file, header file, etc.). With no extension, we lose this capability.
Also, the standard Unix environment will be completely hosed. For example, let's look at foo.C, which currently includes foo.h. I can go into a directory containing these two files and type make foo and the make program will be able to compile foo.C and create foo. This is how it has been for years and with all compilers, not just C or C++. With this new decision, foo.C will include foo and the make utility will create the executable foo, overwriting the header file.
Please, put in the request that we have an extension on all header files. I don't mind having a different header file extension for C++ source, just don't remove it. Currently, in DOS I use the extension .hpp for C++ header files and in Unix I use the extension .H. This makes sense, I think, since it follows the .cpp and .C extensions used for the source.
Another concern, though not as strong as the loss of header file extensions, is the need for separate header files for C++. Right now, with our current compilers, we can make slight modifications to C header files and make them includable in C++ source. Why can't we leave things like this? Why do we have to clutter up our disk space with new header files for C++ which will provide identical functionality? I know it is because of this namespace stuff but can't we do something more intelligent? If we add a using namespace xxx; to C++ so a default namespace will be used, can't we also add a defining namespace yyy; or something equally wordy (since wordy seems to be the in thing to do in languages now) to allow all classes, methods, structures, enums, etc. to be defined within a certain namespace?
If we try really hard, we can make C++ as complex as Ada and no one will use it either. We could even add a bunch of capabilities to startup and exit so that C++ requires an enormous runtime environment, too. Heck, we could do garbage collection automatically and maybe add a DWIM interpreter (Do What I Mean - not what I say). We could get the runtime environment to require 512M of RAM and everyone will need 1G to run anything. Using DSOs and DLLs, though, you'd only need one copy of the runtime environment loaded at a time. Wow, what a good deal! :-)
Thanks for listening to my rants.
Christopher W. Carlson
C++ is arguably a new language heavily based on C, not just a simple extension of C. I argued strongly against the lack of a suffix on header names, but to no avail. It causes equally bad problems with DOS tools. I'm afraid it's too late to get that convention changed. Runtime code size is certainly a major problem, but I have mixed feelings about that. My company, Dinkumware, Ltd., is currently making good money licensing C++ libraries that emphasize space and speed efficiencies. pjp