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 CUJ,
I am employed as a programmer, concentrating on machine control applications. I cannot understand why every programmer that uses C++ for Windows has not switched to Borland C++ Builder. It is so superior to Visual C++ in speed of development, in true reuse of the framework, and ANSI support. Builder is like Visual Basic because it is truly visual development but it is C++. I am not a Microsoft basher, I am even a shareholder. Microsoft says if you want a nice front end, and RAD development environment, use VB to your GUI front end with a VC back end. I challenge you all to try Builder and do the whole job with one tool. I dare your magazine to do a true comparison of VC++ vs. Builder.
Michael Christopher
Embedded Software Manager
Ohio Electronic Engravers
Dayton, Ohio, USAI use C++ Builder in a lot of my own projects, and I agree with you in one respect: for people who don't know (and don't want to know) anything about Windows internals, C++ Builder is a lot easier to use than VC++ when creating simple GUI-based applications. However, I have used the GUI builder feature of C++ Builder only in very small projects. I cannot offer a comparison of, say, Borland's VCL (Visual Component Library) and Microsoft's MFC (Microsoft Foundation Classes). Such a comparison would be important if you were going to develop a GUI-based application of any appreciable size, and it would have to be carried out by someone who understood the requirements of the project.
Beyond that, of the three things you mention that make a compiler "superior" in your view (speed of development, reuse of the framework, and ANSI support) the only one we could say anything objective about would be compliance to the ANSI standard. The best we could do here would be to list the various features (e.g., member templates) supported or not by the two compilers. Even a list such as this would be of marginal utility, however. Consider, for instance, that the libraries supplied with a compiler can easily be just as important as the feature set supported, and evaluating the relative merits of two libraries is yet another can of worms.
There is no meaningful way to compare two products as complex as a compiler in a few thousand words. Compilers and libraries have to be evaluated in the context in which they'll be used. Any magazine article that leads you to believe otherwise is just not telling the truth. mb
Editor,
Greetings! I just wanted to say that I really enjoyed the cover picture on December's graphics programming issue is it supposed to look like what I think it looks like?
No. mb
Dear CUJ,
I just had opportunity to read through the article on singleton creation in a multithreaded environment ("Singleton Creation the Thread-Safe Way," by Jonathan Ringle, CUJ, October 1999).
The author brings up some important considerations for multithreaded environment, and suggests a locking mechanism to avoid creating a second singleton object. I agree with his solution, but I feel he has added extra overhead without needing to. In his article, he describes using a flag as a "lock-hint." Rather than using another variable (the flag), the singleton itself can be used for this. Just as in the original version with the potential race condition, the _instance value can be checked, if it does not exist; then grab the lock, then test again for the value of _instance and create the singleton if needed. Again, the first thread to need the singleton will grab the mutex and create the object. If another thread tests for the object and fails, then it will contend for the mutex and by the time it gets the mutex, the object will exist and the second test will cause the thread to not try to create a new object. This solution accomplishes the same thing, but does not require yet another global object (the flag).
Keep up the good work, I throroughly enjoy reading through your publication.
Thomas Groleau
Benson, ArizonaThanks for the tip. mb
Dear P. J.,
As someone with over 30 years in the business, I found your article in the C/C++ Users Journal, "Just Another Version of Algol," quite interesting.
You mentioned JOVIAL as standing for "Joe's Own VersIon of ALgol." This is slightly incorrect. JOVIAL's principal architect was Jules Schwartz, at the time, the principal scientist of Computer Sciences Corp. With some "pride of authorship" the language developed for the U.S. military was designated as "Jules' Own Version of the International Algorithmic Language."
Hope you find this revealing.
Regards,
John Carroll
Dear CUJ,
To avoid any loss of information transferring from one system to another, perhaps from IEC559/IEEE 754 to other systems using some other mantissa and exponent combination, (or even just sending to a file or paper and reading back in!), I seem to have discovered that one needs more than the digits10 (== 15 for double) precision using:
cout << setprecision (std::numeric_limits<double>:: digits10)than I expected. For example:
cout << 1.0 + std::numeric_limits<double>:: epsilon()outputs just 1, and not the 1.0000000000000002 that one wants to avoid losing that least significant bit.
Even adding an extra digit, as in:
cout << setprecision (std::numeric_limits<double>:: digits10 + 1)doesn't always produce the terminal 2, but
cout << setprecision (std::numeric_limits<double>:: digits10 + 2)does seem to work as expected.
So floating-point constants like pi are best defined to at least this number of digits too.
This is not what I had naively expected from reading the somewhat cryptic definition of digits10.
This may seem an obscure point, but it is important to avoid loss of information to avoid getting slightly different results on different systems. Statistics assumes and works best on continuous input, so one cannot but improve matters by adding extra "noisy" bits or digits at the end.
Dr. Paul A. Bristow
hetp Chromatography
Wilmslow, Cheshire UK
pbristow@hetp.u-net.comThe problem is much harder than it at first appears. Guy Steele and others published papers a decade ago on how to read and write floating-point numbers without such surprising loss of precision. Java requires this behavior. Took Pete Becker a couple of weeks to get it right in our Java library, not to mention a lot of code. pjp
Dear CUJ,
There appears to be an error in one of the code snippets in Gary Powell's "Extending <limits> for Type Safety" (CUJ, December 1999). In the second block of code under the heading "Template Argument Deduction," I believe min(value) and max(value) ought to read min(index) and max(index), respectively. Otherwise, the template is instantiated on the type of value, which is int, and the assertion will always succeed. The text below the code appears to be consistent with these changes, naming index as the variable that provides the template's type.
Also, I would like to comment that all of the examples shown fit into the same pattern of checking not just a bound on a variable's type, but whether or not a particular value can fit within that variable's range. A template like the following could simplify this even further:
template <class TSource, class TVariable> inline bool fits_in(TSource value, const TVariable &) throw() { return std::numeric_limits<TVariable>:: min() < value && value <= std::numeric_limits<TVariable>:: max(); }This would be used as follows:
int FooFunction(int value) { short index; assert(fits_in(value, index)); index = value; ... }Weston Markham
Gary Powell replies:
Dear Weston,
Thank you for the comments about the limits paper. The mistake was made after the galley proofs were sent to me. Fortunately most people will be able to make the correction from the next bit of code.
Your fits_in template is nice in that it encapsulates the whole test in one easy-to-read statement. I skipped making examples for the rest of the limits<> properties as being redundant, the point of the article that while limits<> is fine, one more layer of templates makes it even more useful.
Thanks again,
Gary Powell
I'll 'fess up the mistake was our doing. We truly regret the error. mb
Dear CUJ,
I read with interest the Editor's Forum in your December 1999 issue the commonality between Hardware Design and Software Design is coming back 'round again. A number of years ago my Ph.D. thesis was based on the creation of a "Circuit Specification Language" in effect a Hardware Description Language for VLSI Design. The object of this was to be able to create a design using a C/C++-style language and use this to realise the design across multiple VLSI implementation technologies. The inspiration of this work was partially based on the similarity between porting software programs across multiple platforms and porting hardware designs which the use of object orientation made easier. (For further information see http://eleceng.ukc.ac.uk/~ltw/csl.pdf.)
At that point I was using the advanced state of object-oriented software techniques as a means of helping manage a hardware-design problem. At the same time software technologies were using the advanced state of hardware design in terms of reusable components to solve a software crisis. A number of years later the issues surrounding reusable components in software are still unresolved and hardware technologists are still looking to solve their problems using software-development techniques.
The lessons to be learnt from this seem to be: nobody really has the final answer to the management of complexity there is still no silver bullet, and none expected on the horizon. As systems grow beyond what we have built before there will probably always be a delivery crisis showing up in the costs and timescales related to not really understanding how to build something like this. The process of understanding how to construct complex items in complex and rapidly changing environments will probably also always be slow despite the demands for it to be ever quicker based on customer expectations. It is worthwhile having a broad knowledge base available in an organisation rather than making sure that everyone has very specific skills ready to do their current role. There will always be someone in a different discipline to learn from who would also find it beneficial to learn from you. Not earth shattering relations in the modern world but worth reflecting on.
David Howard
England
waddy100@hotmail.com Hear, hear. mb
Dear CUJ,
I noticed that in his article, "Debugging Component-Based Memory Leaks" in the January 2000 issue, that Ernesto Guisado uses a macro and inheritance to pass type information. It seemed to me that templates and run-time type information would be a better solution in this case. With this in mind, I wanted to try replacing the OBJECT_LOGGER macro with a template. I came up with:
template<class object_t> class object_logger : public log_object { public: object_logger() : log_object(sizeof(object_t), typeid(object_t).name()) {} };Now, you can add logging to a class simply by adding an object_logger member, without any macros:
class my_gizmo { object_logger<my_gizmo> log_object_my_gizmo; // Whatever ... };If one has code that already uses the OBJECT_LOGGER macro, or one does not like coming up with one's own member names, you can redefine the OBJECT_LOGGER macro in terms of this template:
#define OBJECT_LOGGER(name) \ object_logger<##name##> \ __##name##_log_object_;Sincerely,
Matt Seitz
San Jose CAErnesto Guisado replies:
Hi,
Thanks for your comments.
Your code would definitely work, but there are reasons why I prefer my version. You use inheritance too. So it would be macro + inheritance against template + RTTI + inheritance. Although the use of macros is not particularly elegant, it solves the same problem as the template + RTTI combination. I didn't want to obscure the intent of the article by using too many or too advanced features of the language.
C++ was designed following the maxim, "You shouldn't pay for what you don't use." As a consequence, compilers like VC++ V5.0 implement RTTI (and exception handling) as an "optional" feature of the language that you have to explicitly enable. I didn't want to be in the position where I have to explain that you have to enable a specific compiler feature just to use my logger class.
Yes, "you can add logging to a class simply by adding an object_logger member, without any macros," but it's not simpler. If you had to explain your code to a C programmer (remember, it's C/C++ Users Journal), how many C++ features would you have to explain before he can understand the article? And my version?
Your macro example shows another reason why I decided to use a macro instead of templates. For an object that is not going to be used by any client code I didn't want to have to exclicitly name it. The variable is just an artifact I need. The name is totally irrelevant and I don't want to force anybody to choose it for me. On the other hand, if you finally wrapped your code in a macro like mine, the final equation would be <macro + inheritance> against <macro + template + RTTI + inheritance>.
As I said, your solution is perfectly valid, but in my opinion using features of the language not relevant to the point adds nothing but complexity.
Regards,
Ernesto
Dear PJP,
Some historical trivia:
JOVIAL is an acronym for "Jules' Own Version of International Algorithmic Language." Jules is Jules Schwartz of Systems Development Corporation, which was here in Santa Monica CA. IAL was the (a?) progenitor of the various Algols.
Jules implemented the JOVIAL compiler at SDC, where it was used for many projects, and, as I recall, became a standard language for military software.
(I enjoy reading your column!)
Regards,
George Armerding
Armerding@alum.mit.eduYou were one of many who pointed out my memory lapse. Thanks for giving credit where it is due. pjp o