Letters to the Editor
In the January 2000 C++ Report,
Dan Rawsthorne wrote, in Dr. Dan's Soapbox ("What is a Professional Engineer, Anyway?" 12(1): 1214, 44), about Professional Engineers (PEs). He drew a line between PEs and craftsmen such that he intimated there was nothing between the two. The reality is that there are PEs, "regular" engineers, craftsmen, and, of course, pointy-haired management types. When translating this to software development, we have, respectively, PEs, engineers, programmers, and those other folks.
The point is simply that one can be a software engineerdespite the less disciplined nature of software developmentwithout being a PE. Such developers are more skilled and disciplined than programmers, but don't have the responsibilities of a PE.
Rob Stewart, firstname.lastname@example.org
Dan Rawsthorne responds:
In my article I intentionally used the word "engineer" to mean only "Professional Engineer" in order to make my point clear and unambiguous. This is in keeping with what I said in my first column, that "I will ignore details that get in my way, and I will exaggerate some facts at the expense of others if it helps make my point." ("From Concept to Code," 11(4): 5355, Apr. 1999).
I am pleased that my column has provoked some thought. On a more technical note I should say that in Canada and in many states the term "software engineer" is illegal to use because there is no Software Engineering disciplinethe word "engineer" is reserved for such use by law.
I am writing regarding your March 2000 C++ Report column titled "Widgets, Inheritance, and Writing Safe Code" (12(3): 411). In this column, you list three unreasonable statements, saying that polymorphism, STL containers, and exception safety are useless because they cannot be applied to an arbitrary class without a change in the code structure. You assert that the three statements are "equally fruitless." While I agree that they are all fruitless, I do not agree that they are equally fruitless.
For the first statement, inheritance of virtual methods was made part of the language to accomplish polymorphism. To take advantage of polymorphism, a class must implement all the methods to be implemented polymorphically. Inheritance merely formalizes this requirement. Also, adding two words of code [": public Base" Ed.] is hardly a "structure change" in the code, though it is in the runtime representation.
For the second statement, value classes (which are what we would want to collect in STL collections) should already have assignment operators. This is not a structural change; it's good programming practice. Even if a class was designed to hide assignment and copying (by these methods being declared private), pointers and references of that class are still eligible for STL containers.
The third statement is less absurd than the first two. While the Pimpl class is being more and more commonly used, it is not a feature put in by the designers of the class (whereas assignment and inheritance are). It involves an extra file (or two) in the code structure, and makes the class ineligible for public inlined functions (if done in a way to minimize compilation dependencies). It also introduces a slight performance penalty. Creating a new class and putting all the implementation details into it is a much more significant structural change than inheriting from an abstract Base class or providing an assignment operator.
While I would still not assert that this change makes exception safety "useless," I can relate to this statement much more easily than the first two. Perhaps it's because polymorphism and the STL are part of my daily life, and exception safety is not yet. Or that assignment operators and inheritance are part of the language, and Pimpl classes are not. Maybe one day writing a Pimpl class will be as automatic to me as declaring base class destructors virtual. That day is not yet here, for me at least.
Best of luck as editor. I'm sure you'll do a great job.
John McGuinness, John.McGuinness@Anheuser-Busch.com
Thanks for the comments, John. For those just tuning in: In that column I showed that using the Pimpl idiom (to hold class data members at arm's length via a "pointer to implementation") lets us make a class nearly strongly exception safe for assignment even if the class's data members themselves are unsafe to assign or otherwise ornery. In the passage to which you refer, I was trying to argue against what I still think is an invalid objection. Some people have raised the objection: "Aha, you can't always make it safe without using a Pimpl. That means you can't make an arbitrary class exception-safe for assignment without maybe having to change it." My reaction is to say: "Of course. So what?" That's like saying, "Aha, you can't make an arbitrary class usable in place of a Base& without maybe having to change it [to derive from Base]," or "Aha, you can't make an arbitrary class usable in an STL container without maybe having to change it [to support assignment]."
Your point is well taken: The Pimpl exception-safety transformation isn't something directly built into the language syntax, whereas inheritance and assignment are. Still, let me argue why I still think that all three are comparable structural changes. First, inheritance is nearly the strongest relationship, and nearly the tightest coupling, that you can express in C++ (only friendship is stronger/tighter); so choosing to have one class inherit from another does more than change the in-memory layout of objects, but it also changes a program's structure in terms of dependencies and coupling. Second, whether assignment is supported or not is likewise a fundamental aspect of a class, and this choice too has structural consequencesfor example, an assignable object can't have const or reference members, at least not without going through dangerous and unadvisable contortions. Third, we agree that the Pimpl transformation, which better hides a class's internals to avoid compile-time dependencies, is a structural change; where I think we differ is that I think it's not all that different from the other two cases. Whether to use a Pimpl is a choice that should be made by the class's designer, just as much so as the choices of what types to inherit from and what operations to provide.
Finally, thanks for the kind words to this new editor. I hope the resulti.e., this magazineis what you and other readers want to see. If it isn't, I hope the readers will let me know. Ideas and suggestions are always welcome. Enjoy!