Departments


We Have Mail

Letters to the editor may be sent via email to cujed@rdpub.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 Editor,

I've been wondering why arrays in C are not lvalues and I couldn't find a good reason.

Unfortunately, the earliest edition of K&R that I have dates to 1985, when various changes had already taken place in the language. Section 14.3 states that when an array type appears in an expression, it is converted to a pointer to its first element. It says that's the reason why an array cannot be an lvalue.

However, it seems to me that sometimes the pointer could be converted back to an array, e.g.:

void cpy021( int (*m)[10])
{
#ifdef __STDC__
 memcpy(m+1, m+0, sizeof m[1]);
#else
 m[1] = m[0]; /* naive :) */
#endif
}

The best rationale I could come up with is that that feature had been banned because it cannot be always granted. Today, having been exposed to C++, that sort of concern is irrelevant. But, if I remember well, language orthogonality and consistency were being given a somewhat higher priority at the time.

I know you can remember much farther than I, and I'd be delighted to know your opinion about that.

Regards and best compliments for September's STL-bomb!
Alessandro Vesely
MC6192@mclink.it

Arrays are not lvalues because of a fundamental design decision that Dennis Ritchie made in the earliest days of C. He wanted practically any reference to the array a to be equivalent to &a[0]. That way, the subscript operator a[i] can be defined as entirely equivalent to *(a + i) — giving the same (sensible) behavior to p[i] where p is a pointer. With 20-20 hindsight, we can now see that this equivalence was not strictly required to support most of the convenient notation of C. But we now have generations of C programmers who are more or less inured to this equivalence.

Strictly speaking, there's still room in C — syntactically and semantically — to introduce arrays as first-class citizens. I suggested as much at one meeting of X3J11 and got shouted down. However adventuresome the C++ standards committee may be, the C folks were and remain much more conservative. I have to agree that such a change at this date would dramatically increase confusion in an already confusing area. — pjp


Dear PJP:

First, does CUJ have or have any plans for a CD-ROM of back issues like your sister mag WDJ just produced?

Second, why in C/C++ is there not a way to represent binary numbers? (I believe you can only do decimal, octal, and hex.) I was really quite flabbergasted when I discovered this. After all, binary is the root of our machines.

Now, I understand that a 64-bit number in binary would be a little unwieldy, but you can use 0xFF instead of 0x000000FF, so I imagine a similar shortcut would be possible.

Where I wanted to use this was in bit twiddling. It's not too difficult to mentally convert something that is only one bit, but when using a mask that involves many bits, one needs a calculator to get the hex equivalent. Or you have to OR a bunch of single-bit values together. It just seems that code would be more readable if you could see the bit representation directly.

Thanks for the great magazine.
Tom Brown
ROCS, Inc.
tbrown@rocsinc.com

The CD-ROM is already available. Look for an ad in this issue, or check out our Web site at www.cuj.com.

I believe that binary constants have been proposed as an addition to C9X, the revision of Standard C now under way. But I don't know the current status of that proposal. — pjp


Editor,

In the October 1996 issue of The C/C++ Users Journal, in the article, "A Class Hierarchy for Random Number Generation" the sidebar (p. 52) on Linear Congruential Generators (LCG) leads the user to believe that Multiplicative LCGs can have a generation cycle of m-1. In fact they can only have a max generation cycle of m/4 if Zo is odd and a equals 8k+1 for some k. (See Fundamentals of Performance Modeling, by Michael K. Molloy, Ph.D, p. 88.)

Richard Crutchfield
crutchfr@earthlink.net


CUJ,

I have being involved in software development and design for one year now and I have basically learned C and C++ at the same time. I just started reading CUJ and find it extremely interesting and useful.

In the October 1996 issue, there is a very good article in the form of an interview with Mr. Bjarne Stroustrup called "C++: The Making of a Standard." I have been using C++ to implement real-time embedded systems and I have found some resistance. I am told that C++ adds too much overhead and that C could be a better choice. It is now clear to me that C++ is a better choice than C in any case since it provides all the advantages of OOP and, if you don't want to use these nice features, you won't incur any time and/or space overhead.

The problem with that is that I don't really know what is the overhead incurred when it comes to overloading functions, overloading operators, using inheritance, and dynamic binding. Are there any good books and/or articles that describe how the compilers generally implement these OOP features and what is the overhead incurred, so I can decide when it is appropriate to use OOP-specific features in time and/or space critical applications?

Thank you very much.

Alain Bouvier
abouvier@comstream.com

The best source I know, offhand, is probably the series of articles by Dan Saks in these pages. Try the CD-ROM containing back issues. You'll have to scan quite a bit, I'm afraid. You can also profit considerably from the style tips in the books by Scott Meyers. And you should take a look at the Web site for the Embedded C++ Technical Committee, www.caravan.net/ec2plus. — pjp


Dear Mr. Plauger,

I read with interest the excellent article by Martin D. Carroll and Margaret A. Ellis entitled "Obstacles to Inheritability in C++" in the August 1996 issue of CUJ. I have had to tackle some of these issues myself when designing class libaries that I intend to be used by other people.

Although I agree with most of the advice given in the article, I have difficulty with the implication that a class-library designer should predict the ways a user might want to derive from the classes in the library. In my experience, the incredibly wide range of things users want to do with a library makes this exercise generally difficult and often impossible, unless one happens to be clairvoyant.

I very much prefer a philosophy of defining during the design phase how the classes in a library are intended to be derived from. Good documentation for a class library should then include very detailed information on how to derive from its classes, if this is intended.

As the above implies, this does not only apply to inheritance, but to class library usage in general. I believe that (merely human) class-library designers cannot be expected to anticipate the (often boneheaded) things a user might might want to do with their libraries. The intended usage of a library should be well defined and documented. Any usage outside those parameters should not be supported.

Thank you for an informative and thought-provoking article.
regards,
Igor Siemienowicz
igor@adacel.com.au igorsiem@ozemail.com.au

Dennis Ritchie once observed that language design is essentially a bottom-up process. The best designers can envision a multitude of ways the language will be used and will instinctively make the tradeoffs that maximize usability. Class-library design lies midway between language design and more conventional programming. Thus, it does indeed require a touch of clairvoyance to do well. Providing clear definitions, as you describe, is a good discipline that minimizes the need for clairvoyance, however. — pjp


Dear CUJ,

Regarding the letter from Chuck Patterson in the November 1996 "We Have Mail:" Amen Brother...

Now finish your response by helping us make that specialization choice.

I spent 28 years in the practice of consulting engineering to the broadcast industy, only to have that field die during the late 1980s. Since I had used minicomputers in my practice for most of those years, I was able to change professions into networking, communications, and writing some programs.

I realize that my request is beyond reason but had to ask anyway.

Sincerely
Robert L. Miers, PE
Chandler, AZ 85225


Editor:
In regard to the letter from Virgilio Valasco Jr. in the November 1996 issue, please note that primitive types, such as int, do not have constructors and destructors associated with them. Such methods exist only for user-defined types. The syntax he notes:

int x(5);

is called C++ style initialization, whereas:

int x = 5;

is called C-style initialization. You correctly noted that both styles must be supported for the sake of templates. For example, in the classic swap routine:

template <class T>
void swap(T& x, T& y)
{
T temp(x);
x = y;
y = temp;
}

the declaration of temp should use C++-style initialization in case the constructor for class T has been declared explicit, in which case the line would not compile. If T is a primitive type, then the code must still compile.
Eric Nagler
76711.521@compuserve.com

The scalar types must also behave as if they have destructors too, lest certain templates not compile. As a pragmatic soul, the distinction is irrelevant to me whether these are really constructors and destructors, or just happen to look like them. — pjp


Dear Mr. Plauger:

Do you foresee the C++ file streams classes ever supporting shared files, particularly the locking and unlocking of byte ranges? If not, do we ever stand the chance of being able to derive classes from Standard C++ library classes with some reasonable access to the implementation of those classes? For instance, the filebuf class has as a private member a FILE pointer, which in turn contains the operating-system dependent file handle that serves as the argument to most operating system's locking and unlocking calls; protected access to these details would allow developers to build upon the rich feature set of the C/C++ libraries rather than starting new classes from scratch.

Thanks in advance for any insights.
Mark Reichert
reicher1@gate.net

The draft C++ Standard doesn't address file locking, nor does the C Standard. The latter, however, has a clearer tie to the Posix Standard, which does specify how to lock files. Private members are not part of the visible interface mandated by the draft C++ Standard. So the short answer is that C++ will probably not have a standard-conforming, portable way to write code that locks files. At least not in the near future. — pjp


Dear Editor,

I am a new C++ programmer, and I am writing a security program that needs to know the current time. I know I can get it out of the header file <time.h>, but when I try to put it on the screen, it gives me a hexadecimal number. What am I doing wrong?

Thanks,
N. Musurca
slicknick9@aol.com

You need to convert the time and date you get by calling time() to a printable string. Try printing ctime(time()) instead. — pjp