/* */ /* */

Monday, December 24, 2012

New Revision for C++11 Training Materials

In a post in October, I said that the next revision of my C++11 training materials would come out later this year, and that time has come.  This revision is the sixth since the materials were originally published in 2010.  As always, past buyers of the materials are entitled to a free update.  If you've already purchased these materials, you should have received notification from Artima (the publisher) that a new version is available for download.

My normal practice is to publish a changelog along with each new version of the materials, but in this case, I added and removed pages in a number of places, and trying to keep track of and figure out how to describe what got changed where became burdensome, so I stopped trying.  As a result, there is no detailed changelog, but I can offer this high level list of changes:
  • Coverage of enum classes has been added.
  • Coverage of the interaction between noexcept and move operations in the STL has been added.
  • Coverage of universal references has been added, and the example of using them for constructors has been removed.  (This blog post explains why I now think it's generally inappropriate to use universal references for constructors.)
  • Coverage of numeric-string conversion functions has been added.
  • Coverage of alignment control (alignof, alignas, std::aligned_storage, and std::aligned_union) has been added.
  • Coverage of implementation of std::get (for std::tuple) has been added.
  • Coverage of braced initializers has been extended.
  • Coverage of lambdas has been extended.
  • Bugs have been fixed, explanations have been improved, and information has been updated in a number of places.
The overall length of the materials has increased by about 20 pages.

Books on C++11 are beginning to come out, but they're, well, long. For example, the latest C++ Primer is 976 pages, and the upcoming C++ Programming Language is listed at 1040 pages.  If you're looking for more of a technical overview of C++11's primary features than a comprehensive treatment of essentially everything, I think my training materials (383 slides in 22-point type, plus accompanying notes) is a choice you should consider.
 
As before, you can download a free sample to see exactly what you'd be getting if you bought  the materials.  Topics covered in the free sample include:
  • Copying versus moving (high-level overview).
  • Simple example program:  C++98 versus C++11.
  • ">>" to close nested templates.
  • auto for type declarations.
  • Range-based for loops.
  • nullptr.
  • enum classes.
  • Unicode support.
  • Raw string literals.
I originally wrote the following a year ago, but it's still apt:
If you're interested in a book-like publication covering the most important parts of C++11 (both language and library), I encourage you to consider purchasing my training materials.  If you like my other publications, I think you'll like these, too.  To see exactly what you'll be getting, check out the free sample.

Because this publication is in an unconventional format (annotated training materials), is available from a lesser-known publisher (Artima), and is electronic-only (DRM-free PDF), getting the word out about it has been challenging.  I'd appreciate it if you'd let people know about it, whether through blogs, tweets, social networks, email, or that most retro of communications mechanisms, face-to-face conversation.
Thanks,

Scott

Sunday, December 16, 2012

Examples of good code-based digital publications?

In my last post, I wrote:
I [want] to ensure that [my next] book looks good on all target platforms, by which I mean ink on paper as well as various digital representations (e.g., PDF, HTML, ePub, etc.)  I've noticed that many books containing code examples display, er, suboptimally on one or more digital devices, and I want to avoid that.
Over the years, I've heard many complaints about the appearance of code-heavy publications (book or magazine article or blog entry, etc.) on digital devices, but I can't recall any cases of people praising the appearance of a programming piece on the device they use.  I'd like to believe that this is just because I'm wallowing in ignorance.  If you have read a code-heavy publication on a digital device where you felt the job was done well, please tell me!  I'm primarily interested in mobile devices like phones, e-readers (e.g., Kindle or Nook) or tablets.  PDF on a large laptop is not hard to get right.

If you have an example of code-heavy publishing done well on a mobile device, please email or post as a comment the following information:
  • The device being used
  • The title of the publication
  • The publisher
  • The author
  • What about the experience you find especially well done
I really want to do a good job porting my book to various platforms, and the more I can find out about successes that precede me, the better I can do.

Thanks,

Scott

Wednesday, December 12, 2012

Publishing Code on Digital Platforms

I plan to write a new book next year (Effective C++11, about which I'll have more to say later, probably in January), and I'm laying the groundwork for it.  Part of that groundwork is doing what I can to ensure that the book looks good on all target platforms, by which I mean ink on paper as well as various digital representations (e.g., PDF, HTML, ePub, etc.)  I've noticed that many books containing code examples display, er, suboptimally on one or more digital devices, and I want to avoid that.  To that end, I've started a list of characteristics I think code displays should have, i.e., that readers should be able to take for granted in code displays.

A "code display" is code sitting in a paragraph on its own, i.e., like this:
// This code display consists of a class definition and a free function
class Widget {
public:
  explicit Widget();
  Widget(const Widget& rhs);
  Widget(Widget&& rhs);
  ...
};

std::ostream& operator<<(std::ostream& s, const Widget& w);
Here's my list so far:
  • Code should be syntax-highlighted.
  • Code should be copyable and pastable as text. This rules out using images for code displays.
  • Code should be copyable and pastable as code. For example, if the code display has line numbers, there should be a way to copy and/or paste such that the line numbers are omitted.
  • Code should be searchable. This also rules out using images for code displays.
  • Viewing Code displays should not require horizontal scrolling.
  • Code displays should have no bad line breaks.  This means no automatic wraparound due to the code not fitting in the available horizontal space.
There's a caveat to this "code reader's bill of rights." If you choose to view a code display in a "pathological" way, you lose the last two guarantees.  In general, this means that I expect you to have some reasonable horizontal width available on whatever device you're using.  If you view a code display on an iPhone in portrait mode, you're on your own.  If you view code on 10" tablet and set the font size to 200, you're on your own. If you view code on a giant PC screen and set the viewing window to 10 pixels wide, all bets are off.  As an author, I'm willing to do what I must to offer you these guarantees, and I'm willing to browbeat my publisher into offering them, too, but you have to give us a reasonable field to play on.

Are there other things you, as a reader, would like to be able to take for granted when viewing code displays in a technical publication?  Are there problems with code displays on digital devices that you've run into and that are not addressed above?  If so, let me know. Bear in mind that I'm trying to identify basic characteristics you should be able to take for granted, but currently cannot.  I'm happy to hear about nice-to-haves, too (e.g. it'd be nice to be able to click on or gesture over some code and have it automatically sent to an online site such as ideone or Live Work Space to be compiled and executed), but what I'm really interested in are things you should be able to take for granted.

Thanks,

Scott




Saturday, December 8, 2012

More Effective C++ at 30 (Printings)

Today I received something rather remarkable:  a copy of my More Effective C++ from its thirtieth print run. So many printings is uncommon for any technical book, but it’s particularly surprising for this one, because our understanding of what it means to apply C++ effectively has undergone considerable change since the book’s initial publication in 1996. For me, that makes a thirtieth printing kind of a big deal. It’s also a somewhat ironic deal, because, for many years, More Effective C++ was a book I wasn’t especially fond of. Only its longevity has allowed me to develop an admiration and respect for it.

To some degree, books are to authors what children are to parents, and just as parents should love all their children equally, I’ve always felt guilty that I didn't have the affection for More Effective C++ as for my other C++ books, Effective C++ and Effective STL. The reason is simple: writing More Effective C++ was not a terribly pleasant experience.

That’s not what I anticipated when I began. Effective C++ had been a breeze to write, because I’d built it around guidelines and examples I’d refined through my training work with professional developers. For that book, I was so sure about what I wanted to say and how I wanted to say it, the manuscript nearly wrote itself. I probably spent more time worrying about formatting than content. Furthermore, I was excited about the prospect of becoming an author, so even the parts of the project that felt like work were fun and exciting. It was hard work, sure, but it was fun, exciting hard work.

Effective C++ was well received, and being the author of a hit was also fun. I became a columnist for C++ Report, which meant I acquired a soapbox from which to pontificate, and what’s not fun about pontificating? It was fun, fun, fun, all the time, and that was my mindset as I set about work on More Effective C++. It was going to be the fun sequel!

As best I can remember, I produced a draft manuscript without difficulty, and this was sent out for review. That’s when the fun ended. The book, it became apparent, had two problems. First, it was not technically sound. Second, it was irritating to read. One of the reviewers stopped commenting after a few dozen pages, and, having savaged what he’d seen, concluded with “It doesn’t get any better after that.” Ouch.

So much for fun.

There’s no point in asking for comments on a manuscript if you’re going to ignore them. The technical shortcomings of the material were easy to verify. What’s wrong is simply wrong. The comments on my writing style were more difficult to accept. However, these were remarks from people I respected, and if they were willing to take the time to warn me that my prose was more likely to enrage readers than engage them, I owed it to them (and to my future readers) to assume that what they saw was really there. I set the manuscript aside for a few days so I could look at it anew...and so I could prepare for the ordeal.

With my reviewers’ comments in mind, a fresh look clarified things. The manuscript was somewhere between bad and awful, and the reason was obvious. While working on it, I’d been thinking of fun, fun, and more fun. I was having fun writing, and I wanted my readers to have fun reading. But readers don’t turn to a book on C++ for entertainment. They turn to it for information and insight. I’d forgotten that, and it showed in my writing.

I started over.

“This is not a project about fun,” I told myself, “this is a project about useful information for professional C++ developers who have jobs to accomplish. Working on the book means working. There can be some fun along the way, but the essence of the project is careful work yielding practical insights into C++ and its effective application.” With that in mind, I rewrote the book, and the result (after a round of substantially less brutal reviews and the always-necessary copy-editing pass) was what was ultimately published.

Even setting aside that I wrote More Effective C++ twice, working on it was bound to be harder than Effective C++. It wasn’t my first book, so the “Oooh! I’m going to be an author!” factor was missing. I’d put all my best and most established material in Effective C++, so coming up with quality content was a bigger challenge. Furthermore, I’d changed the format of the book. Whereas Effective C++ consists of guidelines that can be explained and justified in a few pages, in More Effective C++ I wanted to do that plus explore some meatier topics—topics that could not be covered in such a format. More Effective C++ is essentially two books stapled together: one containing Effective C++-like guidelines, and another consisting of technical essays on topics like smart pointers, reference counting, and proxy classes. The result is about 50% longer than the first edition of Effective C++—another reason why More Effective C++ called for more effort.

The work was demanding, and I really did treat it as work, but I decided to allow myself one luxury—one Item motivated not by any practical consideration or compelling use case, but solely by my interest in it. One Item for fun. That Item is number 31: “Making functions virtual with respect to more than one object.” The general term for the topic is multi-methods. It’s sometimes also referred to as double dispatch or multiple dispatch, though these latter terms conflate what with how. (What we want is multi-methods. Double or multiple dispatch is how we can implement them. I’m chagrined to admit that among those who have failed to distinguish what from how is me: in More Effective C++, I describe multi-methods, double dispatch, and multiple dispatch as synonyms.)

Curiously, my “fun” Item has emerged as one of the most frequently referenced in the book. Over the years, authors have published increasingly sophisticated ways to attack the problem I explored, often using the same example I employed (handling collisions between objects in a video game). In the “Interesting Comments” section of my online errata list for More Effective C++, I refer to six books, articles, or online discussion threads that address the implementation of multi-methods. In 1998, I was even an outside reader on a doctoral dissertation focusing on the implementation of multi-methods in strongly-typed programming languages.

Also curious is the turn taken by Items 28 and 29, which together examine how non-intrusive reference-counting smart pointers can be implemented. Experience with the code I published motivated me later to advise developers to steer clear of custom code in favor of proven implementations, notably Boost’s shared_ptr (which became the basis for TR1’s std::tr1::shared_ptr, and, ultimately, for C++11’s std::shared_ptr). In Effective STL, I wrote:
The STL itself contains no reference-counting smart pointer, and writing a good one—one that works correctly all the time—is tricky enough that you don't want to do it unless you have to. I published the code for a reference-counting smart pointer in More Effective C++ in 1996, and despite basing it on established smart pointer implementations and submitting it to extensive pre-publication reviewing by experienced developers, a small parade of valid bug reports has trickled in for years. The number of subtle ways in which reference-counting smart pointers can fail is remarkable.
Remembering that I wrote this is easy, because it was quoted in the proposal to the C++ standardization committee that ultimately led to the introduction of shared_ptr (and weak_ptr) into TR1. That’s the kind of thing that warms a fellow’s heart: his inability to publish correct code being used as an argument to expand the standard library.

Compensating somewhat is the recognition that the advice I proffer in Item 33 (“Make non-leaf classes abstract”) has now largely become accepted wisdom in the C++ community. At the time, it ran counter to widespread thinking about object-oriented programming, even though I’d spoken with enough experienced C++ library designers to know that well-engineered libraries generally hewed to the line I advocated. I braced for a backlash from readers aggrieved that I was telling them to abandon the idea that adding a class to a hierarchy was a simple matter of finding a suitable base class and inheriting from it. In fact, my advice was consistent with that idea. I simply imposed a constraint on what it meant to be suitable, and that constraint flew in the face of what was at the time considered a cornerstone of object-oriented programming. That Item may be the one I’m most pleased with, because it provides a technical underpinning for a counterintuitive, yet pervasive, constraint on good hierarchy design.

More Effective C++ was one of the first books to include advice on programming with exceptions, and the essence of that guidance is all but enshrined in the Exception-Aware Programming Hall of Fame: use RAII to manage object lifetimes, prevent exceptions from leaving destructors, catch exceptions by reference, be aware of the costs that exception-based error handling may incur, etc. Interestingly, the term “RAII” doesn’t occur in the book, but the acknowledgments explain why:
The notion of using destructors to prevent resource leaks (used in Item 9) comes from section 15.3 of Margaret A. Ellis’ and Bjarne Stroustrup’s The Annotated C++ Reference Manual. There the technique is called resource acquisition is initialization. Tom Cargill suggested I shift the focus of the approach from resource acquisition to resource release.
Thanks to Tom’s advice, Item 9 is entitled “Use destructors to prevent resource leaks”—the essence of RAII. By the time I wrote the third edition of Effective C++ nearly a decade later, I’d adopted “Use objects to manage resources” as my wording for this kind of guideline, but I’m gratified to see that the exception-related information in More Effective C++ was on target three years before the appearance of what I consider the breakthrough book on programming with exceptions, Herb Sutter’s Exceptional C++.

In fact, viewing the Item title summary that is More Effective C++’s table of contents in this, the dawn of the C++11 era, I’m pleased to see that, fundamentally, all the advice there remains appropriate. Naturally, I’d tweak some things. For example, in light of the utility of some template metaprogramming techniques that I (and pretty much everybody else) was unaware of in 1995, I’d soften Item 7’s “Never overload &&, ||, or ,” to something more like “Be wary of overloading &&, ||, and ,”. Because exception specifications are deprecated in C++11, I’d replace Item 14’s “Use exception specifications judiciously” with something closer to “Prefer noexcept to exception specifications.” Such tweaks notwithstanding, the high-level advice in More Effective C++ suffers from a lot less decay than one might expect from a book in its seventeenth year. I can’t help but be a little proud of that.

The thirtieth printing of More Effective C++ didn’t produce the same book as the first one. As with all my books, I solicit bug reports and other improvement suggestions from my readers, and I keep the book’s errata list online, so everyone can see the problems that have been reported and the ones I have fixed. For each new printing, I do my best to revise the book to address outstanding issues, but sometimes my schedule is such that there’s not time to do it. (The window between being notified of a forthcoming printing and the deadline for revisions is typically rather short.) The 30 printings of More Effective C++ since 1996 have yielded 20 different versions. 

 More than 20 versions have actually been printed, because I’m counting only domestic printings. The book has been printed in alternative forms for English-speaking markets outside the United States (e.g., with a different cover design and less expensive paper for markets where North American pricing is inappropriate). It’s also been translated into a number of foreign languages, including German, Japanese, Korean, Polish, Russian, and both traditional and simplified Chinese. All in all, More Effective C++ has been printed more than 150,000 times in at least ten languages. It’s available in a number of electronic formats, as well.
My collection of More Effective C++es.  Domestic printings are on the left, international versions on the right.  Detail-oriented readers will notice 31 copies of the domestic version.  That's because there were two versions of the third printing.

My little less-loved book has surpassed any reasonable expectations an author could have. Still quietly chugging away in its seventeeth year, still providing useful information to C++ software developers—what more could I ask? As I said, I’ve grown to admire and respect this book—and even to have a parent’s affection for it.