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. Briand:
Please rein in Stan Kelly-Bootle. When reading his columns I can't help but imagine a self-indulgent movie reviewer on cocaine. His writing is verbose to no purpose other than to feed his ego. His language is of a type that I'd rather not see in a serious software journal.
I am reluctant to repeat his words in a letter such as this but they make my complaint so clear that I must. In the June issue he used the word "shit." In the August issue he used the words "piss" and "tit."
The writings of Stan Kelly-Bootle are not worthy of C/C++ Users Journal. The Journal would not be hurt by his absence.
Sincerely,
Robert Penoyer
123 N. New Ave., Apt. D
Monterey Park, CA 91755"Reining in" Stan Kelly-Bootle is like lassoing a swarm of gnats. What's worse, he's likely as not to take that movie reviewer' comment as a compliment. I know Stan's the kind of guy you either hate or you love. I for one enjoy his quasi-permeable insanity. I hope you will give him a chance, and consider that it is not a contradiction for a serious technical journal to have a sense of humor. Thanks for writing. mb
Hi Marc,
I just got my August CUJ and read Mr. Carlson's article. I hope you don't mind if I share some criticisms with you. Firstly, you can indeed name the data segment most anything, but it must also be an ANSI string. Secondly, using a linker flag in project settings to share the segment is harder to maintain than simply adding the line [broken here to fit column]:
#pragma comment(linker, "-section:shared,rws")following #pragma data_seg in the source file itself. Thirdly, the LoadDLL which calls CreateThread should probably call SetThreadPriority(ThreadId, THREAD_PRORITY_LOWEST), since that thread will be sleeping most of the time. Fourthly, using a DLL mapped to both processes which does nothing but loop and read a variable is inefficient. A named mutex between the processes would eliminate the need for the DLL and its loop, making both applications more efficient in both space and time.
Best regards,
Mario Contestabile
MarioC@Computer.Org
Dear CUJ,
While the technique presented in the article "An Automated Process Shutdown DLL" (CUJ, August 1999) will work, it breaks one of the cardinal rules of multithreaded programming and can be significantly improved with a small amount of work. Polling loops are almost always a bad idea in mulithreaded programming and are easily avoided. In this case the loop:
// wait for the shutdown // to be triggered for(;;) { Sleep(1000); if (shutdownProcess == 1) { break; } }chews up a fair amount of time since it executes the comparison about once a second. When you consider that this loop is running in a thread in each separate process that is interested in being shutdown, the CPU cycles really start to add up.
A much better solution would be to use WaitForSingleObject with an infinite timeout on a named kernel object such as a manual reset event. This would allow the thread to not chew up any cycles until the shutdown has been requested. It also eliminates the need for a custom shared data section in the DLL which requires vendor specific compiler pragmas and linker flags.
I've attached a modified version of shutdown.c (see Listing 1) that demonstrates the changes that I outlined.
Sincerely,
/* Andrew */
Software Engineer
BSQUARE Corporation
andrewt@bsquare.com
http://www.halcyon.com/astPaul Carlson replies:
Mario:
CUJ forwarded your critique to me you are absolutely correct in all your comments. With regard to using a mutex, I would probably create an event kernel object and use WaitForSingleObjectEx instead of a named mutex, but in either case, it would be more efficient than polling a flag.
However, as I noted in the article, I had two main objectives:
1) To demonstrate how to launch another separate thread of execution.
2) To demonstrate how to use a shared memory segment.
I really didn't want to get into a discussion of thread synchronization techniques for this article. As I stated in the article, "Of course there may be more elegant mechanisms than this polling mechanism for monitoring shutdown status. The suitability of this mechanism depends on the application." Your mutex would certainly be more elegant and perform better. No doubt about it.
If other developers are interested in multi-threaded programming and thread synchronization techniques, I would refer them to the book Multithreading Applications in Win32 The Complete Guide to Threads, by Jim Beveridge and Robert Wiener. It is a bit dated, especially the MFC-related topics, but is still a good reference.
Thanks for your comments,
Paul
Dear CUJ,
In the June 1999 CUJ article, "Better Assertions for MFC," Mr. Bavestrelli advocates a macro named SAFE. Despite its name, that macro is dangerous. Whereas one must not put required code in an assert statement, SAFE encourages that practice. (I realize that MFC offers a VERIFY macro, and I even use an equivalent, but those macros are a slim wrapper around a statement that would otherwise be present, exactly as is. SAFE obscures the required statement with its other parameters.)
By evaluating its argument twice, SAFE makes it easy to invoke code with side effects even if introduced later during maintenance twice. This will generate errors that could be hard to trace.
Rob Stewart
Giovanni Bavestrelli replies:
Dear Rob,
The article warns very carefully about the double evaluation problem. In my response to Andrei Alexandrescu's mail in the August '99 issue of CUJ you can see what I think about the issue and you can find a better definition of SAFE that does not evaluate its arguments twice.
Best Regards,
Giovanni Bavestrelli
Dear Mr. Briand,
I like the suggestions of version and manifest functions and the freeze' you mention (Editor's Forum, CUJ, October 1999). I wish the Microsoft side would use something like Delphi uses in its VCLs to preclude some of the replacement problems.
Also I'd like to see a Microsoft-only registry only their products could be registered/manipulated through it. A second registry for all third-party folks' terrorizing might help stop the fdisk-format-reinstall' dance that corrupt registries (quite often) make us perform.
Danny C. Mullen
DZMUL@WORLDNET.ATT.NETThanks for your comments. mb
Hi there,
I noticed the Special Request you posted in CUJ about XML ("Call for Papers," CUJ, September 1999). Acutely I am working on this problem too. Just before I read Andrivet's article in the July '99 issue of CUJ, I finished my own script parser and "invented" my own version of "script language," because of my bad experience of MFC's binary serialization scheme. Apparently, XML is better than my home brewed "language," so I want to use XML in the next version of my project to describe the system configuration and save user settings. I have several questions as I start working on the prototype:
1. Where do you save the properties of your real object, in the subitems or in the properties of an XMLItem (a node in the tree).
2. XMLitem is actually a map of string to string (properties) and a map of string to XMLItem (subitems). I think a class's serialization methods can take a XMLItem's reference as parameter, in the place of CArchive in MFC, but the class must know which string maps to which member variable, and must convert between strings and correct types. My question is: is there any uniform way of doing this? I have heard of schema and DTD, but I feel that may be a little overkill in my case.
Another advantage of using XML is, who knows what it implies in the Internet age.
Cheers!
Wei Du
Senior Software Engineer
Auburn Systems, LLCWe are not XML experts here, unfortunately. But I have faced similar choices in my own dabblings with XML. As you may have noticed, there is no obvious one-to-one mapping between XML items and C++ classes. XML provides a way to specify both item "attributes" (which I am guessing is what you mean by "properties") and subitems. C++ classes admit of no such distinction between attributes and subitems. What's more, in C++ you have to specify once and for all (at compile time) which subitems will be present in a class. XML is more flexible.
Of course, you can rule out specifying compound types as attributes, since XML attributes are atomic. In my own projects, I limit attributes to those "pseudo-scalar" types (in which I include string) that should never have null or default values, such as an object's name. Maybe other readers with more XML experience can suggest better guidelines. Thanks for writing. mb o