Departments


Editor's Forum


When I first learned about C++ reference variables, a number of years ago, I did not trust them. I wasn't quite sure what they were made of. Of course I was able to read in countless books and magazine articles that a reference was an "alias" for another variable — whatever that meant. Alias means "another name for," but I don't think C++ authors realized how little meaning that term conveyed. After all, a macro is an alias too, although in a much different sense. We would never say a reference was like a macro. Yet what a reference was like was not forthcoming.

I was just starting to get comfortable with references when I encountered another oddity: a function returning a reference. Now what could that mean? We normally think of functions as returning values, things that take up a space. Even if the thing being returned is a pointer, that pointer is itself a value that requires a few bytes of storage. But a reference is sort of a phantom in the world of variables. In principle, at least, it need occupy no storage. I couldn't see how a function could "return" something so incorporeal.

I was mystified until some C++ author betrayed a dirty little secret: many compilers implement references as hidden pointers. Bing! A light went on; I could envision what was happening at run time. That removed a mental block for me, and enabled me to move toward a more correct understanding of references. Of course, some would say that author committed a terrible sin by discussing a specific implementation. What he wrote was not true of references in general. I say, big deal! This is how people learn — well, most of us, anyway. We need to use concrete, if somewhat innacurate examples as stepping stones to the more abstract and complete. I have no problem with authors discussing implementation, as long as they make the limits of applicability clear.

In the technical publishing business we strive for accuracy, and for the most part, that is a good thing. But sometimes I think we fail our readers by being too careful. We hide behind abstractions, like "alias," for fear of misleading readers. We provide a sterile correctness when we could have provided insight. I think that is the situation that exists today with C++ templates. I can read in a thousand different places what templates are and how to use them. I have yet to read an article that explains how a compiler translates a template into working code. Such an article might talk about compile time, link time, and even finer-grained phases of translation. The article might even discuss the data structures a compiler builds to keep track of templates. In short, the article would provide concrete, juicy information.

I can already hear a few people saying, "You can't talk about that; that's implementation specific." But that is just an excuse for complacency. We can talk about it, if we're humble enough to pay the price — that price being a willingness to be a little bit wrong, for as long as it takes to gain understanding. I would have a much deeper understanding of templates if I knew how one compiler implemented them than if I memorized every clause in the C++ Standard. (By the way, if you are qualified and willing to write on this subject, give me a buzz at mbriand@cmp.com.)

I don't think my program for learning is all that radical. Besides, it's not even mine; it's the way human beings have learned for centuries. We used Newton's Laws of Motion as a stepping stone to the Theory of Relativity. Newton's laws have always been a little bit wrong, but they continue to serve us well. Tomorrow we may use Relativity to jump to something more strange and wonderful. Being 100 per cent right the first time is not an option for us. Given the choice between clueless and a little bit wrong, I'd rather be a little bit wrong.

Marc Briand
Editor-in-Chief