Today’s Friday Thought comes from something I just reread today, written years ago by the Dean himself. He certainly was a master of concise clarity. Enjoy:
"There is a world of difference between ‘Roger’ and ‘Wilco.’"
Robert A. Heinlein, 1958
Today’s Friday Thought comes from something I just reread today, written years ago by the Dean himself. He certainly was a master of concise clarity. Enjoy:
"There is a world of difference between ‘Roger’ and ‘Wilco.’"
Robert A. Heinlein, 1958
In the past few days, I’ve had several people independently send me email to ask related questions about exception specifications. That must be reason enough to echo some answers here.
Background
For background, here are two places where I’ve written about exception specifications:
I’ve taken the liberty of pasting the entire latter reference at the bottom of this post. Enjoy!
Now on to Question the First…
Q1: How can you know you’ve caught everything if you don’t use exception specifications?
Andrew Skypeck asked:
In CCS#75 you suggest that one ought not provide an exception specifications with functions. Without them, how can a user of the function be certain they have caught all possible exceptions without inspecting the code they are calling? This is often not possible for API users that have header files only.
Two thoughts:
First, the way to catch everything is to catch(…), and that always works. You seem to be wanting to use exception specifications as documentation (which is fine), and so you can get the same ability by writing the exception specification as a comment. Note that even if you try to write them all as actual code, you can’t do it in general — notably you can’t do it for templates, because if a template can be instantiated with any type, you generally can’t know in advance what it might throw.
Second, the caller of a function doesn’t always need to catch all possible exceptions; it should only catch the exceptions that it knows how to handle (or translate). Exception safety is not just about making sure that the code that knows how to detect an error throws, and that the code that knows how to handle the error catches; rather, in practice exception safety is largely about making sure the code in between stays out of the way, including that it doesn’t catch and absorb exceptions. For more about this aspect of exception safety, start with these Items in C++ Coding Standards, and follow the references at the end of each Item to dig into the details that interest you:
Which brings us to Question the Second:
Q2: Why not statically enforce exception specifications?
Bob Rossi asked, while kindly citing the above article:
I would like to know what the possibilities are of C++0x enforcing the exception specifications like Java does. Here is a good article describing why exception specifications acting the way they do are currently bad, http://www.gotw.ca/publications/mill22.htm
I must not fully understand the situation. What is wrong with the compiler time checks that Java does to enforce the exception specifications? I find this feature extremely useful as a developer!
The short answer is that nobody knows how to fix exception specifications in any language, because the dynamic enforcement C++ chose has only different (not greater or fewer) problems than the static enforcement Java chose.
If you’re interested in reading more about this, try googling for newsgroup postings, http://groups.google.com/groups?q=sutter+exception+specifications. The following is taken from the second hit, which I wrote last fall:
Essentially, exception specifications are a wonderful idea in basic principle, but no one really knows how to design them.
There are two major approaches, and both have serious problems. Java chose static enforcement (at compile time, as suggested above), and C++ chose dynamic enforcement. Interestingly, I see Java people ask "why not enforce these dynamically?" about as often as I see C++ people ask "why not enforce these statically?"
Briefly:
When you go down the Java path, people love exception specifications until they find themselves all too often encouraged, or even forced, to add throws Exception, which immediately renders the exception specification entirely meaningless. (Example: Imagine writing a Java generic that manipulates an arbitrary type T…)
When you go down the C++ path, people love exception specifications until they discover that violating one means invoking terminate, which is almost never what you want.
So why did C++ do exception specifications the way it did, with dynamic enforcement via terminate? And why did Java do it the other way? In both cases, it seemed like a good idea that avoided some set of known problems, and you can’t always know the new problems you incur instead until you gain experience with multiple releases of large code bases, which means over time.
The future of exception specifications?
Bob responded by asking why we don’t just fix exception specifications, or remove them entirely until something better comes along. Those are good questions.
Taking the latter part first: As tempting as it may be, one can’t just rip out a language feature because one decides it isn’t working out quite right. The primary reason is that there are people using the feature, and breaking existing legal code is, well, rude.
What about fixing exception specifications? That would be nice, and I think nearly everyone I know is willing to consider changing them, but only if: (a) there is a well-understood replacement (there isn’t today), and (b) there was a good way to deal with migration from existing code which may rely on the existing feature.
Deliberate change with a strong dose of backward compatibility is always the key. This one needs more deliberation, at least for now, and isn’t expected to change in C++0x.
Epilogue: C++CS Item 75
I’m sure Addison-Wesley won’t mind overmuch if I paste one Item here in its entirety. It has been slightly reformatted for the web.
75. Avoid exception specifications.
Summary
Discussion
In brief, don’t bother with exception specifications. Even experts don’t bother. The main problems with exception specifications are that they’re only “sort of” part of the type system, they don’t do what most people think, and you almost always don’t want what they actually do.
Exception specifications aren’t part of a function’s type, except when they are. They form a shadow type system whereby writing an exception specification is variously:
Illegal: In a typedef for a pointer to function. Allowed: In the identical code without the typedef. Required: In the declaration of a virtual function that overrides a base class virtual function that has an exception specification. Implicit and automatic: In the declaration of the constructors, assignment operators, and destructors when they are implicitly generated by the compiler.A common but nevertheless incorrect belief is that exception specifications statically guarantee that functions will throw only listed exceptions (possibly none), and enable compiler optimizations based on that knowledge.
In fact, exception specifications actually do something slightly but fundamentally different: They cause the compiler to inject additional run-time overhead in the form of implicit try/catch blocks around the function body to enforce via run-time checking that the function does in fact emit only listed exceptions (possibly none), unless the compiler can statically prove that the exception specification can never be violated in which case it is free to optimize the checking away. And exception specifications can both enable and prevent further compiler optimizations (besides the inherent overhead already described); for example, some compilers refuse to inline functions that have exception specifications.
Worst of all, however, is that exception specifications are a blunt instrument: When violated, by default they immediately terminate your program. You can register an unexpected_handler, but it’s highly unlikely to help you much because you get exactly one global handler and the only way the handler could avoid immediately calling terminate would be to rethrow an exception that is permissible—but because you have only one handler for your whole application, it’s hard to see how it could do useful recovery or usefully know what exceptions might be legal without trivializing exception specifications altogether (e.g., following the discipline of having all exception specifications allow some general UnknownException eliminates any advantage that having an exception specification might have had in the first place).
You generally can’t write useful exception specifications for function templates anyway, because you generally can’t tell what exceptions the types they operate on might throw.
Paying a performance overhead in exchange for enforcements that are nearly always useless because they are fatal if they ever fire is an excellent example of a premature pessimization (see Item 9).
These is no easy fix for the problems described in this Item. In particular, the problems are not easily solved by switching to static checking. People often suggest switching from dynamically checked exception specifications to statically checked ones, as provided in Java and other languages. In short, that just trades one set of problems for another; users of languages with statically checked exception specifications seem to equally often suggest switching to dynamically checked ones.
Exceptions
If you have to override a base class virtual function that already has an exception specification (e.g., ahem, std::exception::what), and you don’t have the ability to change the class to remove the exception specifications (or to convince the class’s maintainer to remove them), you will have to write a compatible exception specification on your overriding function, and you should prefer to make it no less restrictive than the base version so as to minimize the frequency with which it might be violated:
// in a class written by someone else,
// the author used an exception specification,
// and if you can’t get him to remove it…
class Base { // …
virtual f() throw( X, Y, Z );
};// … then in your own class your override
// must have a compatible (and preferably
// the identical) exception specification
class MyDerived : public Base { // …
virtual f() throw( X, Y, Z );
};[BoostLRG]’s experience is that a throws-nothing exception specification (i.e., throw()) on a non-inline function “may have some benefit with some compilers.” Not a stunning endorsement from one of the most highly regarded and expertly designed C++ library projects in the world.
References [see the C++CS online bibliography for reference details and other links]
[BoostLRG] – [Stroustrup00] §14.1, §14.6 – [Sutter04] §13
For nearly a decade, I’ve had a plaque bearing that question on my desk.
I think the question is valuable because it goes directly to motive. It’s also a deliciously contextual question — it means something different every minute, depending on what you’re up to. Here are a few scattered examples:
Nobody’s perfect. I’ve wrestled with these and other questions, as I’m sure you do too, and try to improve a little every day and every year.
Being intentional is more than just about programming. We can get there if we keep trying.
Last week, Anders Hejlsberg, Erik Meijer, Brian Beckman and I recorded an interview/chat that covered a range of topics related to programming and languages.
The video is now available online. Here’s the summary pasted from the Channel 9 site:
Software Composability and the Future of Languages
Anders Hejlsberg, Herb Sutter, Erik Meijer, Brian BeckmanHow will imperative programming languages evolve to suit the needs of developers in the age of Concurrency and Composability? What role can programming languages play in enabling true composability? What are the implications of LINQ on the future of managed (CLS-based) and unmanaged(C++) languages? How will our imperative languages (static) become more functional (dynamic) in nature while preserving their static "experience" for developers?
Answers to these questions and much more are to be found in this interview with some of Microsoft’s leading language designers and programming thought leaders: Anders Hejlsberg, Technical Fellow and Chief Architect of C#, Herb Sutter, Architect in the C++ language design group, Erik Meijer, Architect in both VB.Net and C# language design and programming language guru, and Brian Beckman, physicist and programming language architect working on VB.Net.
This is a great conversation with some of the industry’s most influential programming language designers. Tune in. You may be surprised by what you learn…
Apologies in advance if the video doesn’t work for some combination of platforms and browsers.
What does the word "success" mean to you? There’s no shortage of opinions about what Success should mean and upon which particular Altar of Success we ought to sacrifice our lives and energies. That doesn’t mean those opinions are worth paying attention to. As a quote attributed to Lily Tomlin put it nicely, ‘the trouble with the rat race is that even if you win, you’re still a rat.’
In that spirit, I enjoyed reading the reminder in this picture. The quote is from Ichiro Suzuki, a baseball player (currently for the Seattle Mariners) and clearly a success in his field. I found Ichiro’s words printed on a Starbucks coffee cup, and fancied them even more than the maple latte inside. I hope you enjoy them too.
P.S.: Yes, I do more reading than just Starbucks cups.
Last week I reread an old classic SF novel, and noticed some remarkable details in this passing comment by one character about the fictional 21st-century Utopia:
"… there are too many distractions and entertainments. Do you realize that every day something like five hundred hours of radio and TV pour out over the various channels? If you went without sleep and did nothing else, you could follow less than a twentieth of the entertainment that’s available at the turn of a switch! No wonder people are becoming passive sponges — absorbing but never creating. Did you know that the average viewing time per person is now three hours a day? Soon people won’t be living their own lives any more. It will be a full-time job keeping up with the various family serials on TV!"
Arthur C. Clarke, Childhood’s End, 1953
Of course, in this passing reference Clarke probably wasn’t trying to make a serious prediction. Nevertheless, Sir Arthur’s astute understanding of the future growth and effects of TV is impressive, all the more so given TV’s primitive state when he wrote that in 1953.
Some perspective. According to Wikipedia and TerraMedia, in 1953 the first commercial TV licenses were granted in the states of Arkansas, Idaho, Kansas, Maine, Mississippi, Montana, Nevada, North Dakota, Oregon, South Carolina, and South Dakota. Canada had only just begun its first regular TV transmissions the year before, and the states of New Hampshire, Vermont, and Wyoming wouldn’t issue their own first licenses until 1954. 1953 also saw the first TV coverage of the Academy Awards, and the launch of TV Guide.
How did Clarke do? With the benefit of hindsight, let’s see:
As we often say today, "Who knew?" In this case, Sir Arthur did. Last month he turned 89, and his literary output is still going strong. Hats off to the man!
I’m pleased to announce that Bjarne and I are going to have another two-day event co-located with SD West in San Jose, California, this March. Most of the talks are new ones we’ve never given publicly before, along with one or two classics.
Here’s the info page on my site: Stroustrup & Sutter #3.
For convenience, here’s a cut-and-paste of the session topics and abstracts. I look forward to seeing many of you in San Jose! Best wishes,
Herb
8:15-8:30am Welcome (Herb Sutter)
8:30-10:00am Concepts (Bjarne Stroustrup)
C++ templates are immensely flexible and the basis of most modern C++ high-performance programming techniques and of many elegant library designs. They are the key language feature behind the standard library’s algorithms and containers: the STL. However, they can also be tricky to use, cause spectacularly bad error messages when misused, and sometimes require unreasonable amounts of code to express apparently simple ideas. C++0x will address these issues directly, and the key to resolving the problems with templates without loss of flexibility or loss of performance is "concepts." Concepts provide a type system for C++ types and for combinations of C++ types and values. Thus, we are able to provide what feels a lot like conventional type checking for template arguments (including simple and elegant overloading based on template arguments). This presentation explains the notion of concepts and shows how to use concepts to write clearer and more robust generic code using templates. People who can’t wait for C++0x before trying out concepts (and other new C++0x features related to generic programming) can try the proof-of-concept implementation, ConceptGCC.
10:00-10:30am Break & mingling
10:30am-12:00pm Modern C++ Libraries: The Good, the Better, and the Sublime (Herb Sutter)
Besides the C++98 standard library, the key portable C++ libraries to know about today include the draft C++0x standard library extensions, the second set of standard library extensions now under parallel development in the ISO C++ committee (aka "TR2"), and of course the Boost libraries. This talk selects and presents what we consider to be some of the most important facilities in these libraries, guidance on the best practices for using them effectively, and a liberal dose of context and commentary.
Noon-1:30pm Lunch & mingling
1:30-2:45pm How To Design Good Interfaces: The Basic Interface Principles (Bjarne Stroustrup)
So: We have classes, derived classes, virtual bases, templates, const, overloading, exceptions, and a host of other useful language features. How do we use them to produce well performing maintainable code? All too often we get seduced into using powerful language features to write clever (i.e., complicated) code rather than to simplify our interfaces and to make the organization of our code easier to understand. This presentation is a tour of the most useful C++ features from the point of view of how they can be used to express the structure of code and to define interfaces that serve basic needs such as flexibility, early error detection, acceptable compile time, performance, decent error reporting, and maintainability.
2:45-3:00pm Break & mingling
3:00-4:30pm Design Patterns and Policy-Based Design (Herb Sutter)
This talk provides an overview of the importance of patterns and their role in C++ libraries. In the course of this material we will take an insightful look at two patterns in particular, showing the many implementation choices and tradeoffs available within the single pattern design, and how to choose among them for best effect. We will also see in detail how to apply policy-based design techniques to create very flexible and efficient implementations of a pattern in the form of pluggable and reusable template code.
4:30-4:45pm Break & mingling
4:45-5:30pm Grill the Experts: Ask Us Anything! (Bjarne Stroustrup & Herb Sutter)
This is your opportunity to get "thought leader" answers to your favorite C++ questions! We strongly encourage you to submit your questions in advance, preferably by email or in writing at the beginning of the seminar. Audience questions will also be taken from the floor. Both instructors will answer as many questions as time permits.
8:30-10:00am C++0x Overview (Bjarne Stroustrup)
We now know the basic outline of what will become C++0x (hopefully C++09). This presentation articulates the main principles of the design of C++0x, outlines the ISO C++ standards process, summarizes the new features and libraries, and gives key examples using new features. Major features, such as concepts, the memory model, and major libraries (such as threads and regular expression matching) are covered by other tutorials, so they will be only briefly mentioned here. The focus of this presentation is the various "minor" features, such as the unified initializer syntax (including variable length initializer lists), generalized constant expressions, "strong" enumerations, the new for statement, static assertions, and rvalue references. But a language is far more than a mere list of features: My aim is to show how these features fit together and fit with C++98 features to better support programming techniques. As ever, the ultimate aim of this language design is to allow clearer expression of real-world ideas, leading to better-performing and easier-to-maintain code. Even the "minor features" can significantly affect your programming style.
10:00-10:30pm Break & mingling
10:30am-Noon Machine Architecture: Things Your Programming Language Never Told You (Herb Sutter)
High-level languages insulate the programmer from the machine. That’s a wonderful thing — except when it obscures the answers to the fundamental questions of "What does the program do?" and "How much does it cost?" The C++ programmer is less insulated than most, and still we find that programmers are consistently surprised at what simple code actually does and how expensive it can be — not because of any complexity of C++ the language, but because of being unaware of the complexity of the machine on which the program actually runs. This talk examples the "real meanings" and "true costs" of the code we write and run especially on commodity and server systems, by delving into the performance effects of bandwidth vs. latency limitations, the ever-deepening memory hierarchy, the changing costs arising from the hardware concurrency explosion, memory model effects all the way from the compiler to the CPU to the chipset to the cache, and more — and what you can do about them.
Noon-1:30pm Lunch & mingling
1:30-2:45pm C++ In Safety-Critical Systems (Bjarne Stroustrup)
C++ is widely used in embedded systems programming and even in safety-critical and hard-real-time systems. This presentation discusses how to write code in these highly demanding application areas. First the mapping of C++ code to hardware resources is reviewed and the basics abstraction mechanisms (classes and templates) are reviewed from the perspective of this kind of code. Then, the JSF++ coding rules are examined as an example of a set of domain specific rules. These rules have been and are being used for the development of millions of lines of C++. Questions addressed include: "Can I use templates in safety-critical code?" (yes, you can and must) and "Can I use exceptions in hard-real time code?" (sadly no, not with the current level of tool support). Predictability of language features and minimization of
programmer mistakes are key notions.
2:45-3:00pm Break & mingling
3:00-4:30pm Writing Robust Concurrent Code Using the New C++0x and "TR2" Concurrency Libraries (Herb Sutter)
Concurrency is "the" must-know item for the next decade in any code where CPU performance is important, because from now on only well-written concurrent applications will be able to exploit the CPU power in commodity hardware. Where C++98 didn’t even have the notion of threads, C++0x and the second set of standard library extensions (aka "TR2") are adding strong support for concurrency, including useful libraries for atomic operations, threads and thread pools, locks, futures, and other useful features. This talk is not just a tour of these features; rather, it teaches important design principles and best practices for multithreading and shows how to write code to implement them using C++0x and TR2 features.
4:30-4:45pm Break & mingling
4:45-5:30pm Discussion on Questions Raised During the Seminar (Herb Sutter & Bjarne Stroustrup)
This panel is set aside for follow-up comments and discussion on issues that are raised during the seminar. During the other talks and panels, or during between-session chats, questions often come up that the instructors want to research. Some of the resulting information will be of general interest, and this final panel provides the needed convenient opportunity to promulgate it to everyone.
“Hey, buddy, want a free laptop?” Assuming it was being offered by a legitimate store, and not from the back of a nondescript pickup truck parked behind the local mall, a lot of people would presumably say, “well, duh, sure!” Or would they?
A question that’s buzzing ’round the blogosphere is whether it’s right for companies like AMD and Microsoft to give, and/or for bloggers to accept, such free-as-in-beer laptops with Vista installed. Presumably AMD hopes that the bloggers will like the hardware and write about it so that other people will hear how great it is and want AMD-based laptops too. Presumably Microsoft hopes that the bloggers will like Vista and write about it so that other people will hear how great it is and want Vista too.
Robert Scoble thinks it’s “an awesome idea.” On the flip side, Joel Spolsky thinks it’s “ethically indistinguishable from bribery” and points out some interesting consequences. Me, I just love a chance to test the value of a potential principle derived from analyzing one situation by seeing how well it extends to similar situations. After all, if two questions X and Y are of the same kind, though perhaps different in degree, then an answer that’s true for X should also be true for Y. (If cannonballs fall downward when released, so should watermelons.)
So consider book publishers:
When a new book comes out, the publisher routinely mails out free copies to as many potential reviewers as they can possibly think of. Depending on the book, you could think of it as dead-tree spam. Anyone who writes for any moderately relevant media outlet that some potential book purchaser might read is a target liable to be deluged. Yes, publishers give those $50 books away for free, to the point where I’ve long ago had to ask publishers to PLEASE STOP SENDING ME BOOKS WITHOUT ASKING FIRST (er, sorry, that caps lock key gets jammed sometimes). You can find books in print by Scoble, by Spolsky, and by me — and I’m sure all of our publishers routinely give away free copies of our new books to potential reviewers, hoping that making them available will increase the chances of getting a good review (as opposed to, say, no review at all if the potential reviewer misses the book entirely in the avalanche of new titles clamoring for their attention).
Sending free books to potential reviewers is a common practice. Readers seem to like it, because reading the buzz helps them to find out about new books that might interest them. On the other hand, if Spolsky is right, should we view “free books!” as an attempt to unfairly manipulate the buzz, an attempt which furthermore could cast a shadow of doubt on all reviews and reviewers, bloggers or otherwise?
So consider some variants of the question: Is it ethical for a vendor of
to give away free products to potential reviewers, hoping to generate coverage?
Of course, the product costs vary; (most) laptops are more expensive than (most) books. But those are differences in degree, not differences in kind. If you think the price point matters, then what is the price boundary between “fair gift” and “bribery,” and why?
I won’t try to say what The Answer is; everyone needs to decide what their own answer will be, and act accordingly. I’m just observing that a consistent answer should apply well to all of these situations, including the “any product” general case.
What do you think, Robert and Joel?
Disclosure and disclaimers
Whereas the current tempest is about AMD-based machines for bloggers, I’m writing this on a free machine I was given (a) by a different vendor and (b) for a different reason. The machine I’m using now is an Intel quad-core machine that Intel gave me under the same “try it out, let us know what you think” conditions, because I’m a member of a Microsoft team whose software they presumably want to work well on Intel hardware. Both AMD and Intel routinely supply free machines for this purpose to various Microsoft teams. For the record, a few months ago AMD offered me a laptop just like the ones being talked about in the current tempest, but I turned it down because I already had an adequate laptop and had no use for another one.
Unlike the current tempest about machines given in hopes of garnering positive reviews, the machines supplied to internal Microsoft teams are presumably not given in hopes that we’ll blog about it (the vast majority of the recipients aren’t bloggers or other writers), but rather to make sure we develop and test our future software products on their hardware so that the software will be likely to work well on that hardware.
Extra question for bonus points: Is it ethical for a {book|software|hardware|other} vendor to give away free products to potential value-add third parties, hoping to encourage add-ons that work well with their core product?
I’m a Microsoft employee, but I don’t speak for Microsoft or even particularly care that it’s one of the names involved in the original question that I’m now generalizing. I’m interested in the question for its own sake, and I’m glad that Scoble and Joel have posted thoughtful comments on this topic.
P.S.: Like I said, Intel didn’t give me this machine because I’m a blogger. But since we’re already having this discussion, and because I am in fact a blogger, and I am at this very moment blogging, and I feel like saying that I do like this Intel quad-core machine, I’ll say so: I like it. Thanks, Intel. It’s a great, snappy machine. Oh, and its runs Vista just fine, and I like Vista too (well, except that Vista won’t run Civilization 4 well, but that’s another story…).