Wednesday, December 17, 2014

The Evolving Search for Effective C++

The video of my keynote address at Meeting C++ 2014 on December 5 has just been posted to the Meeting C++ Channel at YouTube. I was given a long time slot (two hours), so I addressed two rather different topics, both based on my work of the past quarter century identifying and promulgating guidelines for effective C++ programming.

The meat of the first topic is an explanation of how one of the guidelines in Effective Modern C++--"Consider emplacement instead of insertion"--came to have the form that it does. It has a lot of hard-core C++ content, though I hope that the secondary lesson about the importance of seeking feedback on prospective programming guidance also comes through. This part of the talk runs about an hour.

The second topic is about disseminating information in written and presentation form, and it's not about C++ at all. Rather, it's about issues I think authors, publishers, and trainers need to consider when packaging technical information for consumption in an age where writing is in print or digital form and where the reach of a technical talk is often much greater in recorded form than through a live presentation. This part of the video is about 30 minutes long.

At the end of the talk is some 20 minutes of Q&A.

I worked hard preparing this presentation, and I'm pleased with the way it came out and with the material I covered. I hope you enjoy it.

Scott

Friday, December 5, 2014

Effective Modern C++ Exists!

I arrived in Berlin last night (where I'm participating in Meeting C++) to find a package waiting for me with two print copies of EMC++! At about the same time, I found out that the initial print run had sold out by the time it hit the warehouse, so a second printing has been scheduled in about a week. If you didn't get a copy of the book from the initial print run, don't feel bad: the books I ordered for some training I'll be doing next week got pushed back to the second printing, too. The only copies I'll see for a while are the two you see in the picture.

For my Meeting C++ keynote this morning, O'Reilly gave me a discount code for both print and digital versions of EMC++, and since I shared it with the conference attendees, I'll share it with you, too:  AUTHD. That should save you a sweet 50% off the ebook and a nearly-as-sweet 40% off the print book. (Inexplicably, the discount isn't applicable to the print+ebook bundle, so if you want both, put them into your cart individually, because the total price will then beat the already-nicely-discounted bundle pricing.)

In the meantime, Addison-Wesley has extended their deep ebook Deal of the Day discount on the digital versions of my earlier C++ books to a second day, so if you're wondering what to do while you're waiting for your print copy of EMC++ to arrive, don't overlook the possibility of clicking and shopping for EC++, MEC++, and ESTL.

Scott


Thursday, December 4, 2014

Special Sale: Digital Bundle of EC++, MEC++, and ESTL for $40!

Addison-Wesley has chosen my Effective C++ Digital Collection (i.e., digital versions of Effective C++, Third Edition, More Effective C++, and Effective STL) as their December 4 ebook Deal of the Day. The bundle, which normally sells for $95.99, has been marked down to $39.99. At only about $13 per book, I think that's a very attractive price.

These books have not been updated for C++11, but most of the information in them remains fundamentally sound, and of course if you haven't yet migrated to C++11, they're as useful now as they've ever been. (For my perspective on the relevance of the information in Effective C++ in the C++11 era, take a look at this blog post.)

Happy shopping!

Scott




Friday, November 28, 2014

First Review of Effective Modern C++


The first review (that I'm aware of) of the "published" version of EMC++ just appeared at the CoderGears Blog. The review gives these five reasons to read the book:
  1. It explains well the motivations behind the standards.
  2. It shows the relation between the new features.
  3. Provides some basic and pragmatic rules to modernize your C++ code base.
  4. Samples are very easy to understand.
  5. Smart pointers demystified.
The review concludes:
In the final this book is really Effective, it explains the motivations behind the new features and help you  understand the whole picture about the new standards. Beginer or even expert C++ developers will find it very useful.
Check out the full review for all the details.

For addition comments on the book, take a look at the reviews at O'Reilly's web site. Currently all the comments there refer to pre-publication drafts that we released, but I'm pleased to report that everybody gave those drafts five stars out of five.

Speaking of the O'Reilly web site, they're currently running the de rigueur post-Thanksgiving sale, so ebooks (including EMC++) are 50% off until December 2. That means you can pick up the digital version of EMC++ for $21.49 via the apparently-inspired-by-FORTRAN66 discount code CYBERDY. You can order here.

Scott

Wednesday, November 19, 2014

EMC++ Display Issues on Kindle

I've received some reports about how Effective Modern C++ doesn't render well on Kindle, with code comments not aligning correctly and a narrow single-character ellipses ("…") being visually indistinguishable from a wider three-character ellipses ("..."). In response to my queries about these kinds of problems, my production team at O'Reilly told me:
One of the Kindle options available is "Publisher Font." If the user selects this font, the comments will be aligned and the difference between the ellipses will be visible. None of the other font options available on the Kindle device will display the alignment in the proper way. By default, Kindle devices don't default to Publisher Font, which is a shame. Users will have to make the selection manually.
I've noted some other Kindle-related issues at the EMC++ Errata List. If you find additional problems, let me know, and I'll see what we can do about addressing them in revised versions of the digital versions of the book. (Revised versions are free to people who've bought the digital version of EMC++.)

Scott

Monday, November 10, 2014

EMC++ Exits Publishing Purgatory!

I just received the following from O'Reilly:

Congratulations! Your book went to print on Friday, and we've now completed production. The Retail Availability Date for ebooks on oreilly.com and Amazon is tomorrow, 11/11. For print books, it's estimated at 12/2. 
Finally!

Scott

Monday, October 20, 2014

Wanted: Good & Bad UI Examples from Mobile Realm

From time to time, I give a presentation on what I consider to be the most important guideline in software development: Make interfaces easy to use correctly and hard to use incorrectly. Over the years, I've collected a variety of interface examples that either adhere to this rule or, more commonly, violate it, and I try to update the presentation to keep the examples contemporary.

I'd like to add some examples from the mobile realm (smart phones, ebook readers, tablets), but--gasp!--I don't have any such devices. Yes, I'm stuck in a technological time warp hovering in the 1990s. But you're not, and I'm hoping you'll be willing to share with me examples of mobile interfaces that are easy to use correctly and hard to use incorrectly...or that aren't. If you could provide screen shots, that'd be ideal.

I break "easy to use correctly and hard to use incorrectly" down into the following sub-guidelines, so interfaces that either uphold these ideas or trample all over them would be especially helpful:
  • Adhere to the principle of least astonishment.
  • Choose good names.
  • Be consistent.
  • Use progressive disclosure.
When I talk about interfaces, that includes APIs, so I'd be happy to receives examples of good and bad API designs for mobile platforms, too.

Thanks for any help you can offer.

Scott

Sunday, October 19, 2014

New ESDS Book: Effective Ruby

I'm pleased to welcome another book with a full-color interior into my Effective Software Development Series, Peter J. Jones' Effective Ruby.

I'm not a Ruby developer, but Peter's writing is a pleasure to read, and his experience with and enthusiasm for the language is clear. For those of you who do code in Ruby, I encourage you to check out this very nice book.

Scott

Monday, September 22, 2014

The Four Stages of Doneness

People have been asking me when Effective Modern C++ will be done. (My wife is among them, and our dog has been giving me funny looks, too.) For my earlier books, the "when will you be done" question was easy to answer, because my deliverable was camera-ready PDF. A book was done when I sent in the final PDF.

For EMC++, I've decided that it makes sense to break "done" down into four stages:
  • Done, Stage 1, is when I send in a "final" manuscript for typesetting.
  • Done, Stage 2, is when I submit information to be used for preparing the index.
  • Done, Stage 3, is when I approve the typeset versions of the book.
  • The final stage of doneness is when I approve the index. At that point, the book is ready for publication.
We're currently in the middle of Stage 3. O'Reilly send me their initial cut of PDF and digital files (i.e., epub and Kindle-compatible mobi) for the manuscript I submitted at Stage 1. The process of my revising these files is known as QC1. I've sent back my QC1 comments, and I expect to get QC2 files in a few days. QC1 didn't include the index, but the QC1 index is supposed to show up in my inbox any time now.

In the meantime, work on the book's cover is moving along, and above you can see what I expect to be the final front cover image. We're also honing in on the text to go on the back of the book. O'Reilly's marketing department and I have gone through four iterations so far. It's not easy to describe in ~250 words what a ~300-page technical book is about and why you absolutely positively must buy it, but we're doing our best :-).

I continue to expect the book to be available in October.

I'll keep you posted on the book's progress. Nobody wants this book to be fully done more than I do, but it's important that it be not just done, but done well. The final two stages of doneness will help ensure that that's the case. When it comes out, it will be the first book I've written that was designed to render well on both paper and digital devices. If you consume it digitally, it should look as good (and be as useful) regardless of whether you prefer portrait or landscape, color or monochome, and large or small fonts. The only formatting assumption I make is that I can fit 64 monospaced characters on a line, so some code examples could get a bit whacked out on small cell phones, but other than that, my goal is that EMC++ should look good and convey useful information no matter how you read it.

Scott

Tuesday, September 9, 2014

CppCon Hair Poll


During my talk at CppCon yesterday, I decided to liven things up by asking the audience to answer a question that comes up often: who does my hair style make me look like? People volunteer answers to this question--which, until now, I've never asked--on a surprisingly frequent basis.
I wasn't able to show the results of the poll in real time, because I didn't realize that if I got more than 100 responses, I'd have to pay to see the data. Serves me right for forgetting the fine print I'm sure I agreed to when I started with SurveyMonkey.

I've now ransomed the data, and the final results (when CppCon ended) are as follows:







Wednesday, September 3, 2014

50% Off Effective Modern C++ Ebook

From now through September 9, O'Reilly's running a sale: all EBooks are 50% off, including the Early Release version of Effective Modern C++.  (Buying the early release version also gets you a copy of the final digital edition when it comes out, which is slated to be in about a month.)

My book is currently at the top of the O'Reilly Best Seller List (okay, it's not so much at the top as in the upper left corner, but I choose to interpret that in the best possible light), so if you've been thinking of buying the digital version of the book, this is a great way to help keep EMC++ #1 while making sure that O'Reilly and I don't make much money off of it  :-)


Scott

Monday, August 25, 2014

Upcoming Appearances: 2 Continents, 5 Countries, 8 Cities, Several Topics

Now that work on Effective Modern C++ is approaching completion, it's time to get out and see the world...and give technical presentations. Between September and December, I'll be giving talks in the United States, Germany, England, Poland, and Latvia. Geographically, the European presentations work out this way:
In the USA, I'll be in Bellevue, WA, Cambridge, MA, and Bala Cynwyd, PA.

The topics I'll be addressing are rather varied, including a lot of information about C++11 and C++14, the importance of CPU caches for software performance, general advice on interface design, plus some reflections on thinking about and writing "Effective" books.

You'll find details on all my upcoming presentations at my Upcoming Talks page, e.g., exact dates, locations, and topics. I think all the presentations will be fun, but let me call out two in particular:
  • If you're interested in material from Effective Modern C++, the most comprehensive seminar I'll be giving on that topic will take place on October 7-8 in London.
  • A special attraction of C++ and Beyond in Stuttgart is looking like it might be a full-blown bar brawl between me and Herb Sutter. In recent weeks, he and I have been going back and forth about the wisdom (or lack thereof) of advising people to use pass-by-value in function interfaces. We've exchanged some posts on this topic in comments on my blog and in posts to a Microsoft C++ MVP mailing list, plus there have been some behind-the-scenes email messages, and at this point, having carefully weighed all the facts, it looks like the only thing we fully agree on is that the other person means well, but is terribly misguided. Herb's German may be better than mine (it definitely is), but when it comes to parameter-passing advice, that boy is going down!
I hope to see you in Bellevue, Cambridge (MA), Bala Cynwyd, Stuttgart, London, Wrocław, Riga, or Berlin later this year.

Scott

Wednesday, August 20, 2014

Near-Final Draft of Effective Modern C++ Now Available (plus TOC and sample Item)

Effective Modern C++ is moving closer and closer to reality. This post contains:
  • Information about availability of an almost-final draft of the book.
  • The current (and probably final) table of contents.
  • A link to the I-hope-I-got-it-right-this-time version of my Item on noexcept.

Draft Book Availability

A revised and nearly-final manuscript is now available through O'Reilly's Early Release Program and Safari Books Online's Rough Cuts program. The prose still needs to be sanded down a bit, but practically speaking, this is the final stream of words that will make up the book. Remaining tasks include double-checking the code samples, index generation and final formatting (i.e., typesetting), but this should be quite close to what gets published.

I've left the line numbers in for the online drafts, because that makes it easier for people to report errors to me. The really truly honest-this-is-it version of the manuscript is due to O'Reilly in early September, so if you see anything that needs improvement, please let me know by the end of this month!

Probably-Final Table of Contents

Here's the current table of contents. I'm not wild about the title of the final chapter ("Tweaks"), so if you have suggestions for a better title, let me know.
CHAPTER 1  Deducing Types
  Item 1:  Understand template type deduction. 
  Item 2:  Understand auto type deduction. 
  Item 3:  Understand decltype. 
  Item 4:  Know how to view deduced types. 

CHAPTER 2  auto
  Item 5:  Prefer auto to explicit type declarations. 
  Item 6:  Use the explicitly typed initializer idiom when auto deduces 
           undesired types. 

CHAPTER 3  Moving to Modern C++
  Item 7:  Distinguish between () and {} when creating objects. 
  Item 8:  Prefer nullptr to 0 and NULL. 
  Item 9:  Prefer alias declarations to typedefs. 
  Item 10: Prefer scoped enums to unscoped enums. 
  Item 11: Prefer deleted functions to private undefined ones. 
  Item 12: Declare overriding functions override. 
  Item 13: Prefer const_iterators to iterators. 
  Item 14: Declare functions noexcept if they won't emit exceptions. 
  Item 15: Use constexpr whenever possible. 
  Item 16: Make const member functions thread-safe. 
  Item 17: Understand special member function generation. 

CHAPTER 4  Smart Pointers
  Item 18: Use std::unique_ptr for exclusive-ownership resource management. 
  Item 19: Use std::shared_ptr for shared-ownership resource management. 
  Item 20: Use std::weak_ptr for std::shared_ptr-like pointers that can dangle.
  Item 21: Prefer std::make_unique and std::make_shared to direct use of new.
  Item 22: When using the Pimpl Idiom, define special member functions in the
           implementation file.

CHAPTER 5  Rvalue References, Move Semantics, and Perfect Forwarding
  Item 23: Understand std::move and std::forward. 
  Item 24: Distinguish universal references from rvalue references. 
  Item 25: Use std::move on rvalue references, std::forward on universal
           references.
  Item 26: Avoid overloading on universal references. 
  Item 27: Familiarize yourself with alternatives to overloading on universal 
           references.
  Item 28: Understand reference collapsing. 
  Item 29: Assume that move operations are not present, not cheap, and not used. 
  Item 30: Familiarize yourself with perfect forwarding failure cases. 

CHAPTER 6  Lambda Expressions
  Item 31: Avoid default capture modes. 
  Item 32: Use init capture to move objects into closures. 
  Item 33: Use decltype on auto&& parameters to std::forward them. 
  Item 34: Prefer lambdas to std::bind. 

CHAPTER 7  The Concurrency API
  Item 35: Prefer task-based programming to thread-based. 
  Item 36: Specify std::launch::async if asynchronicity is essential. 
  Item 37: Make std::threads unjoinable on all paths. 
  Item 38: Be aware of varying thread handle destructor behavior. 
  Item 39: Consider void futures for one-shot event communication. 
  Item 40: Use std::atomic for concurrency, volatile for special memory. 

CHAPTER 8  Tweaks
  Item 41: Consider pass by value for copyable parameters that are cheap to 
           move and always copied.
  Item 42: Consider emplacement instead of insertion. 
Technical writing archeologists may wish to compare this TOC with the versions I showed on 18 March 2014, 5 April 2013, and 29 January 2013. I told you things would change!

Close-to-Final Item on noexcept

I posted drafts of my Item on noexcept on 31 March 2014 and 4 February 2014, so I felt obliged to show you the final-unless-I've-really-made-a-serious-mistake version. Here it is:
Let me know what you think. You've never been shy before, and I have no reason to think things will be different this time around :-)

Scott


Wednesday, August 13, 2014

Quick Test Needed for Boost.TypeIndex under Clang

I don't have Clang here (Windows ghetto, sorry), and I haven't been able to find an online Clang compiler that has the Boost headers available, so I'd be grateful if somebody would run the following program under Clang with the latest Boost and let me know (as a blog comment, so that people will know that the work has already been done) what the output is.

Thanks.

Scott


#include <iostream>
#include <vector>
#include <boost/type_index.hpp>

template<typename T>
void f(const T& param)
{
  using std::cout;
  using boost::typeindex::type_id_with_cvr;
  // show T
  cout << "T = "
       << type_id_with_cvr<T>().pretty_name()
       << '\n';
  // show param's type
  cout << "param = "
       << type_id_with_cvr<decltype(param)>().pretty_name()
       << '\n';

}

class Widget {};

std::vector<Widget> createVec()
{
  return std::vector<Widget>(5);
}

int main()
{
  const auto vw = createVec();
  if (!vw.empty()) {
    f(&vw[0]);
  }
} 

Thursday, July 24, 2014

Should move-only types ever be passed by value?

[For this post, I'm going to pretend that std::unique_ptr is a type, instead of a template, because the issue being examined is independent of what a std::unique_ptr points to.]

Suppose I want to pass a std::unique_ptr to a constructor, where the std::unique_ptr will be moved into a data member. The std::unique_ptr parameter thus acts as a sink. To the extent that we have enough experience with C++11 for wisdom about it to be conventional, said wisdom seems to be that the std::unique_ptr should be passed by value. In his GotW 91 solution, Herb Sutter argues for it. The High Integrity Coding Standard has it as a guideline. (It cites Herb's article as the source.) In his C++ Reference Guide, Danny Kalev argues for it. Many StackOverflow answers repeat this advice.

But recently Matthew Fioravante brought a StackOverflow question to my attention showing a problem resulting from declaring a std::unique_ptr by-value sink parameter, and later Matthew suggested that sink parameters of move-only types should be passed by rvalue reference. This is a very interesting idea.

Suppose you see this function signature:
void f(SomeType&& param);
What does this tell you about param? The fact that it's an rvalue reference tells you that it's a candidate to be moved from, and the usual expectation is that it will be. In other words, it's a sink parameter. Note that this is completely independent of param's type. Even without knowing anything about SomeType, we can conclude that param is a sink parameter.

If SomeType happens to be std::unique_ptr, nothing changes: param is still a sink. There's no need for a special rule for std::unique_ptrs that tells us to pass them by value to indicate that they're sinks, because we already have a way to unambiguously say that: pass them by rvalue reference.

Going back to the idea of a constructor moving a std::unique_ptr into a data member, this is what the code looks like using pass by value:
class Widget {
public:
  explicit Widget(std::unique_ptr ptr): p(std::move(ptr)) {}

private:
  std::unique_ptr p;
};
Now consider this calling code:
std::unique_ptr up;

Widget(std::move(up));
What's the cost of getting up into p? Well, the parameter ptr has to be constructed, and the data member p does, too. Each costs a move construction, so the total cost is two move constructions (modulo optimizations).

Now consider the same thing using pass by rvalue reference:

class Widget {
public:
  explicit Widget(std::unique_ptr&& ptr): p(std::move(ptr)) {}

private:
  std::unique_ptr p;
};

std::unique_ptr up;

Widget(std::move(up));
Here, only the data member p will be constructed, so the total cost is only one move construction.

Unless I'm overlooking something, passing sink parameters of type std::unique_ptr by value is inconsistent with our usual idiom for expressing the idea of a sink parameter (i.e., to pass by rvalue reference), and it's less efficient, too. My sense is that the conventional wisdom regarding sink parameters of type std::unique_ptr is all messed up.

Which leads to the question: how did it get messed up?  I believe what happened was that people noticed that for maximal efficiency when passing lvalues and rvalues of a particular type that needed to be copied inside the function, you needed to either overload on lvalue references and rvalue references, or you needed to pass by universal reference. Both approaches have problems (overloading doesn't scale to multiple parameters, and universal references suffer from the shortcomings of perfect forwarding, lousy error messages, and sometimes being too greedy). For cheap-to-move types, people found, you can use pass by value with only a modest efficiency loss, and the conventional wisdom, in large part based on a David Abrahams' blog post, "Want Speed? Pass by value", came to embrace that idea.

The thing is, for move-only types like std::unique_ptr, you don't need to worry about dealing with lvalues, because lvalues get copied, and move-only types aren't copyable. So there's no need to overload for lvalues and rvalues, hence no scalability problem for multiple parameters. Which means that the motivations for replacing pass by reference--which is what the conventional wisdom from C++98 always dictated--with pass by value don't exist for move-only types.

My feeling is that Matthew Fioravante may well have hit the nail on the head here: there is no reason to use by-value parameters to express "sinkness" for move-only types. Instead, the usual rule of passing sink parameters by rvalue reference should apply.

The special case of considering the use of pass by value for always-copied parameters really only applies to types that are both copyable and movable, and only in situations where overloading and the use of a universal reference is not desired.

What do you think? Is there ever a time where move-only types should be passed by value?

Scott

Saturday, July 19, 2014

Free Excerpt from Draft EMC++ Now Available

O'Reilly has made the TOC, Introduction, and first chapter ("Deducing Types") from the draft version of Effective Modern C++ available for free download. That's roughly the first 40 pages of the book, including Items 1-4. The PDF is available here.

I hope you enjoy this sample content, but I can't resist reminding you that this is from a draft manuscript. The final version will be better.

As always, I welcome suggestions for how this material can be improved.

Scott

Friday, July 18, 2014

Is the non-pointer syntax for declaring function pointer parameters not worth mentioning?

In my view, one of the most important favors a technical writer can do for his or her readers is shield them from information they don't need to know. One of my standard criticisms of authors is "S/he knows a lot. S/he wrote it all down." (Yes, I know: the "his or her" and "s/he" stuff is an abomination. Please suffer in silence on that. There's a different fish I want to fry in this post.)

I try not to commit the sin of conveying unimportant information, but one of the hazards of spending decades in this business is that you learn a lot. After a while, it can be hard to evaluate what's worth knowing and what's best left unsaid. With that in mind, the current draft of Effective Modern C++ contains this passage (more or less):
Suppose our function f can have its behavior customized by passing it a function that does some of its work. Assuming this function takes and returns ints, f could be declared like this:
     void f(int (*pf)(int));         // pf = "processing function"
It’s worth noting that f could also be declared using a simpler non-pointer syntax. Such a declaration would look like this, though it’d have the same meaning as the declaration above:
     void f(int pf(int));            // declares same f as above

One of my reviewers argues that the second way of declaring a function pointer parameter is not only not worth noting, it's not worth knowing. That means I should omit it. But I find myself reluctant to do that. I like the fact that function pointer parameters can be declared without throwing in additional parentheses and figuring out which side of the asterisk the parameter name has to go on. But maybe that's just me.

So what do you think? Should I jettison the aside about the asterisk-free way to declare the parameter pf, or should I keep it?

Thanks,

Scott

Friday, July 11, 2014

Draft Version of Effective Modern C++ Now Available

A full draft of Effective Modern C++ is now available through O'Reilly's Early Release program and Safari Books Online's Rough Cuts program.

The cover design for the book has changed. I'm the common crane no longer. Now I'm the fruit dove. I'm not sure what to make of this. Is going from common to fruity an upgrade?

My editor explained the reason for the avian switcheroo:
Since we are going full color for the book, the animal on the cover is going to be full color. The common crane isn't super colorful so we are switching to the fruit dove because it is filled with color.
During the early release it will be in black and white and the color will make its appearance soon.
The big information here is that O'Reilly has decided to print the book in full color. That's a first for me, and it means that the print book will display the different colors I originally put into the manuscript with only digital publishing in mind.

Well, the print book might display those colors. I'm not preparing the formatted content for this book. Instead, I'm working on a manuscript into which I put all the logical information that O'Reilly will need to produce the appropriate formatting for the files that will ultimately be used for publication and distribution. These will include PDF, ePub, and Kindle-compatible .mobi. So text in my manuscript that's red or blue or tan may not show up in those colors in the final product.

However, those colors will show up in the Early Release version of the book, because that document is simply a PDF print-out of the manuscript I'm working on. Please don't assume that the Early Release document reflects what the final book will look like. Even if O'Reilly chooses to use the colors I selected, they'll definitely clean up many aspects of the page layout that I designed to be seen only by me and my technical reviewers.

The Early Release book reflects the state of the manuscript as of about six weeks ago. Since then, I've read through the several hundred comments I got from my reviewers. Of the 315 pages in the manuscript, only 91 survived unscathed. That means that over 70% of the pages in the Early Release version have problems (that I know about). Some issues are small, e.g., misspellings or grammatical errors. Others involve important technical shortcomings that I'll have to think hard about how to address. To date, my favorite error report concerns a page in the manuscript where I managed to mis-translate a simple C++14 lambda expression into a corresponding C++11 lambda or call to std::bind in three different ways. I got it wrong. Three times. In three different ways. On one page. 

The draft book is available either as a standalone purchase or though Safari Books Online. At Safari, the book is currently associated with yet a third cover design (a hummingbird), but I believe we're going with the dove. Yet maybe not. I'm less in the loop on this stuff than you might think an author would be.

If you read the draft Items I posted earlier (here and here), you may be disappointed or even alarmed to see that the Items in the Early Release draft are essentially the same as what I posted. Relax. In the past few months, I've been focusing on finishing a full draft of the book, so work on revising existing Items got pushed to the back burner. I'm tending to those burners now, so the final versions of the Items will include changes in my thinking based on the comments I've received. 

I'm a little nervous about making this draft available. My normal modus operandi is to make things as good as I can before I publish them. What you're seeing in this case is a draft that was as good as I could make it before I sent it out for technical review. Based on the comments of my reviewers, I'd say it's not in bad shape, but there are a lot of places (some 70% of them) that need work. If you see opportunities for improvement, feel free to let me know about them, either by using the O'Reilly or Safari online errata reporting mechanisms or by sending me email (smeyers@aristeia.com). I don't expect to have time to respond to or to even acknowledge every report that comes in, but I assure you that I'll read them all and do my best to incorporate them into the final version of the book.

Scott

Wednesday, June 25, 2014

Another New Video

When I recently posted about five new videos, I didn't realize that Yandex had published my 11 June presentation at the Moscow C++ Party. There I gave a talk, "Why C++ Sails When the Vasa Sank," which is almost a bookend for the talk I gave at the D Conference last month.
"Why C++ Sails..." is my attempt to explain why C++, despite its size and complexity, continues to be a successful and important programming language.

My comments at the beginning of the video probably make more sense if you know that I had just been introduced in Russian, which is a language I don't know.

I think the double-wide format Yandex published that shows the speaker on one side of the video and the slides on the other works really well. That's overlooking, of course, that the speaker in this case is me. Yeesh. Talk about a need for a makeover...

I realize that other outlets (e.g., the isocpp.org blog) have already reported the existence of this video, and it's got at least two independent threads at reddit (here and here), but I wanted to hold off announcing it until it had been added to my web site's Online Videos and Past Talks pages, including links to downloadable video and presentation materials. Things have been a bit backed up here, hence the delay.

Scott

Tuesday, June 24, 2014

The Drawbacks of Implementing Move Assignment in Terms of Swap

More and more, I bump into people who, by default, want to implement move assignment in terms of swap. This disturbs me, because (1) it's often a pessimization in a context where optimization is important, and (2) it has some unpleasant behavioral implications as regards resource management.

Let's consider a simplified case of a container that contains a pointer to its contents, which are stored on the heap. I'm using a raw pointer, because I don't want to abstract anything away through the use of smart pointers.
class Container {     
public:
  Container& operator=(Container&& rhs);

private:
  int *pData;           // assume points to an array
};
Implementing the move assignment operator using std::swap, the code looks like this:
Container& Container::operator=(Container&& rhs)
{
  std::swap(pData, rhs.pData);
  return *this;
}
Swapping two pointers calls for three pointer assignments,
template<typename T>
void swap(T& lhs, T& rhs)
{
  auto temp(lhs);
  lhs = std::move(rhs);
  rhs = std::move(temp);
}
so the cost of implementing move assignment using swap is three pointer assignments.

However, if we assume that an empty container has a null pData pointer, move assignment can be implemented using only 2 pointer assignments:
Container& Container::operator=(Container&& rhs)
{
  delete [] pData;
  
  pData = rhs.pData;
  rhs.pData = nullptr;

  return *this;
}
I'm ignoring the delete for now, but we'll get back to it later. At this point, I want to observe that non-swap move assignment performs only 2/3rds the assignments of its swap-based cousin. That's important, because move operations should typically be as efficient as possible. Remember that they're optimizations of copy operations, and if you're not concerned about their efficiency, why not just omit them and let rvalues be copied? My feeling is that the fact that a class author went to the trouble of adding support for move operations is a sign that the author perceives the class to be one where speed is important. If that's the case, it seems unreasonable to pay a premium to put the object being moved from into the state of the target of the assignment when it's cheaper to put the object into a different, but equally valid (typically default-constructed), state. After all, the semantics of move assignment typically don't specify the state of the source object of the move after the assignment has been performed, so if callers can't rely on it having the state of the target object before the assignment, why pay for it?

But back to the delete. Regardless of which move assignment implementation is used, the delete will eventually be performed. If it doesn't take place in the move assignment operator for the object that's the target of the move assignment, it'll probably occur in the destructor of the object that's the source of the move assignment. The cost therefore doesn't vary between the implementations, but when you incur that cost does, and that can be important.

Suppose that Container objects typically use a lot of memory--enough that you have to worry about it. Now consider the following scenario:
{
  Container c1, c2;
  ...
  c1 = std::move(c2);
  ...
}
In the non-swap implementation of move assignment, c1's memory is released at the point of the assignment, but in the swap version, that memory becomes associated with c2, and the memory may not be released until the end of the scope. That might well surprise the caller, who could hardly be blamed for thinking that when an assignment was made to c1, c1's old resources would be released. And it could certainly increase the maximum amount of memory used by the application at any given time.

In my experience, the impact of move-assignment-by-swap on the timing of resource release isn't as well known as it should be, even though the issue was well described many years ago (e.g., Thomas Becker  here and David Abrahams here).

Now, bear in mind that I said at the outset that I was disturbed by people who, by default, want to implement move assignment in terms of swap. I have no issue with developers who, consciously aware of the performance and behavioral implications of move-assignment-via-swap, choose to use it anyway. For some types, it may be a perfectly valid implementation choice. My concern is that it's gaining a reputation as the way to implement move assignment, and I don't think that's good for C++.

Am I mis-analyzing the situation?

Scott

Effective Modern C++ Status Report

In recent days, two major milestones for Effective Modern C++ have been achieved.  First, I sent a draft of the book's Introduction out for technical review. That was the last part of the book to be written, so I finally have a full draft manuscript. Second, I received an image of the book cover from my publisher, so I now know what the book will look like. My editor informs me that I'm the common crane, which elicited the same response from me and my wife: "common?!"

Working with O'Reilly is new for me. My past C++ books were published by Addison-Wesley, and my relationship with AW continues (both for past books as well as for books in my Effective Software Development Series). For Effective Modern C++, however, I concluded that O'Reilly was a better fit for me, and I'm quite pleased to be working with them.

A complete draft manuscript and a front cover design do not a book make. There's still a lot of work to be done, and I thought you might be interested in the schedule for it:
  • Now until July 31: I revise the manuscript to take comments from my technical reviewers into account. I currently have over 70 reviewer email messages (some extremely long and detailed) waiting to be processed, and I expect that number to increase significantly by the end of this month, which is when I've requested that reviewers get me their remarks.
  • August 1-15: I produce the book's index. This is my least favorite part of book creation, and I warn my wife well in advance that I'll be unusually irritating to be around during this time. Coming up with terms to index, including text rotations (e.g., "universal references, versus rvalue references," "rvalue references, versus universal references," "references, rvalue vs. universal") and page ranges is tedious, at best, and the tools available to get this information into a manuscript (e.g., into Microsoft Word, which is what I'm using) are primitive to the point of sadistic. There are professional indexers, but my experience (as well as that of other authors I know) has been that if you want a useful index for a book on C++, the content has to be created by the author. How practical it would be to have me identify the content and somebody else do the entry into the manuscript, I don't know. Index preparation is highly iterative, so the process would be more collaboration than hand-off, and my one prior experience with index collaboration did not go well.
  • August 16-30: A copyeditor goes over the entire book, looking for errors and inconsistencies in grammar, spelling, style, labeling, and more. No matter how clean you think your manuscript is and no matter how many people you've had review it, getting it back from a copyeditor is always a humbling experience.
  • September 1-5: I edit the manuscript one last time, taking the copyeditor's comments into account.
  • September 5: I deliver a final manuscript to O'Reilly. 
  • Early October: Digital versions of the book become available.
  • Late October: Print versions of the book become available.
If you're dying to see what's in the book, and you don't mind dealing with a manuscript that's in draft form (and hence contains technical errors, awkward prose, Item titles in need of revision, primitive diagrams, confusing explanations, and, I hope, some stuff in decent shape), Effective Modern C++ will be part of O'Reilly's Early Release Program, meaning you'll have a chance to see the book in the same form as my technical reviewers. You'll also be able to offer comments on it. As things stand now, the book is slated to be available in Early Release form the week of July 7th.


And now, if you'll excuse me, I have hundreds of reviewer comments to process...

Scott

Saturday, June 21, 2014

Five New Videos

It seems that every place I go these days, people are pointing a camera at me and pressing Record. As a result, there are five new videos available at my Online Videos page:
Happy video viewing!

Scott

Monday, April 21, 2014

Three Worthwhile std::enable_if Blog Posts

As I continue my work on Effective Modern C++, I'm pleased to see that the pile of stuff I need to read or reread (or reread again), because it might be useful in the book, is getting smaller. Today I finished my second full draft of my chapter on rvalue references, move semantics, and perfect forwarding, and part of that process was reviewing some interesting blog posts that appeared at Flaming Dangerzone. All address std::enable_if, in one way or another. My first draft of the chapter discussed std::enable_if, but for the second draft, I was pleased to get rid of the material, because (1) it's hard to explain, (2) I think it's too advanced and specialized for the kind of book I want to produce, and (3) I think I found a better way to solve the problem I'd been using std::enable_if for. (To be more precise, I believe that a better way was suggested by one of the technical reviewers of the initial draft of that chapter.)

Book or no book, the blog posts were interesting in a "template metaprogramming makes my head hurt" kind of way, so if you like that kind of headache, would like to better understand std::enable_if and its applications, and have not seen these articles, I recommend them:

Remastered enable_if
To SFINAE or not to SFINAE
Beating overload resolution into submission

Scott

Monday, April 14, 2014

"Hello, World" Podcast with Me


Shawn Wildermuth's Hello World Podcast consists of interviews with developers, authors, speakers, etc., about their programming roots, and recently he asked me to participate. If, for some inexplicable reason, you're interested in hearing about how I played teletype-based computer games in the early 1970s, how I took umbrage when told my programming resembled FORTRAN when it should have been BASIC, and how I came to write Effective C++, have a listen.


Scott

Monday, March 31, 2014

Declare functions noexcept whenever possible?

In the comments following my last post, there was some controversy regarding the wording of my advice on noexcept functions. My advice is "Declare functions noexcept whenever possible." Some people appear to be concerned that this could be misconstrued as advocating noexcept even when it makes no sense, but I think the advice is a reasonable conclusion to the Item that supports it. I posted a draft version of that Item in early February, but I've revised the draft since then, and I'm making the current draft available now:

The current draft of "Declare functions noexcept whenever possible."

I'd be interested to hear what you think of (1) the wording of the Item title and (2) the contents of the Item itself. I'd also be interested to know what you think about these questions:
  • Should I say that constexpr functions are normally good candidates for noexcept?
  • Do lambdas get special consideration, or should they, too be declared noexcept whenever possible. If they're special, why?
  • Do inline functions get special consideration, or should they also be declared noexcept whenever possible? If they're special, how so?
Please let me know what you think.

Thanks,

Scott

Tuesday, March 18, 2014

Book Report: New Title, New TOC, New Sample Item

The purpose of this post is to update you on the status of the book I'm working on. It includes a new working title, a revised table of contents and a new draft sample Item.

Thanks to comments on my blog post asking for suggestions about how to name the book, I've changed the working title to Effective Modern C++, and I've accustomed myself to distinguishing the abbreviation EMC++ (the current book) from MEC++ (More Effective C++). Sharp-eyed readers may have noticed that the new title has already appeared on a talk I'll be giving in June at the Norwegian Developers Conference.

I recently finished the 32nd Item for the book, thus giving me drafts of five full chapters. The math still shows that about 40 Items will fit in the book's allotted 300 pages, so yesterday I took a hatchet to the prospective table of contents and chopped the number of Items down from 51 to 41. (Why 41? Because I have a feeling that one of the Items I've written will eventually get jettisoned as not being important enough to make the final cut.)  Here's the current draft TOC. The chapters I've written are 1-4 and 6 (i.e., chapters 5 and 7 remain on my todo list).

Chapter 1 Deducing Types
  Item 1: Understand template type deduction.
  Item 2: Understand decltype.
  Item 3: Know how to view deduced types.

Chapter 2 auto
  Item 4: Prefer auto to explicit type declarations.
  Item 5: Remember that in variable declarations, auto + { expr }
          yields a std::initializer_list.
  Item 6: Be aware of the typed initializer idiom.

Chapter 3 From C++98 to C++11 and C++14
  Item 7: Distinguish () and {} when creating objects.
  Item 8: Prefer nullptr to 0 and NULL.
  Item 9: Prefer alias declarations to typedefs.
  Item 10: Prefer scoped enums to unscoped enums.
  Item 11: Prefer deleted functions to private undefined ones.
  Item 12: Declare overriding functions override.
  Item 13: Prefer const_iterators to iterators.
  Item 14: Use constexpr whenever possible.
  Item 15: Make const member functions thread-safe.
  Item 16: Declare functions noexcept whenever possible.
  Item 17: Consider pass by value for cheap-to-move parameters that
           are always copied.
  Item 18: Consider emplacement instead of insertion.
  Item 19: Understand special member function generation.

Chapter 4 Smart Pointers
  Item 20: Use std::unique_ptr for exclusive-ownership resource
           management.
  Item 21: Use std::shared_ptr for shared-ownership resource
           management.
  Item 22: Use std::weak_ptr for std::shared_ptr-like pointers that can
           dangle.
  Item 23: Prefer std::make_unique and std::make_shared to direct use
           of new.
  Item 24: When using the Pimpl Idiom, define special member
           functions in the implementation file.

Chapter 5 Lambda Expression
  Item 25: Avoid default capture modes.
  Item 26: Keep closures small.
  Item 27: Prefer lambdas to std::bind.

Chapter 6 Rvalue References, Move Semantics, and Perfect Forwarding
  Item 28: Understand std::move and std::forward.
  Item 29: Distinguish universal references from rvalue references.
  Item 30: Pass and return rvalue references via std::move, universal
           references via std::forward.
  Item 31: Avoid overloading on universal references.
  Item 32: Understand alternatives to overloading on universal
           references.
  Item 33: Understand reference collapsing.
  Item 34: Assume that move operations are not present, not cheap,
           and not used.
  Item 35: Familiarize yourself with perfect forwarding failure cases.

Chapter 7 The Threading API
  Item 36: Make std::threads unjoinable on all paths.
  Item 37: Specify std::launch::async if asynchronicity is essential.
  Item 38: Be aware of varying thread handle destructor behavior
  Item 39: Consider void futures for one-shot event communcation.
  Item 40: Reserve std::atomic for concurrency, volatile for memory-mapped
           I/O.
  Item 41: Employ sequential consistency if at all possible.

You may want to compare this to the initial preliminary TOCs I posted here and here to confirm that I wasn't kidding when I said that things would change. Things might change in the above TOC, too, but this one will be a lot more stable than the earlier versions.

The most recent Item I wrote was "Distinguish () and {} when creating objects." I blogged about one aspect of this topic here, and I thought you might be interested to see what I came up with. I've therefore made the current draft of this Item available, and I welcome your comments on it. Like almost all Items I've written, it's too long, so I'm especially interested in suggestions on how I can make it shorter, but I welcome all suggestions for improvement.

As things stand now, I'm hoping to have a full draft of the book by the end of April. We'll see how it goes.

Scott

Upcoming Public Presentations

2014 is shaping up to be a year with more public presentations than usual. As always, you can find links to all my scheduled talks at my Upcoming Talks page, but here are the ones scheduled so far:

On May 22, I'll giving a keynote address at the D Conference, The Last Thing D Needs. That'll take place in Meno Park, CA. I'm deliberately publishing no description of this talk, because I'd like to maintain the air of mystery engendered by the organizers' asking me to give a talk at conference on a programming language other than the one I'm normally associated with :-)

On June 4, I'll be giving four talks in Oslo at the Norwegian Developers Conference. They're introducing a C++ track this year, and two of my talks will be part of that: Effective Modern C++ and C++ Type Deduction and Why You Care. Of the other two, one will be on interface design (Better Software--No Matter What: The Most Important Design Guideline), and the other will be on performance (CPU Caches and Why You Care).

On September 17, I'll again present CPU Caches and Why You Care, this time in Bala Cynwyd, PA (near Philadelphia). That will be an evening presentation sponsored by Susquehanna International Group.

On October 7-8, I'll be doing a two-day seminar in London for Learning Connexions on material taken from the book I'm currently working on. The seminar is Effective C++11/14 Programming.


There are other presentations in the planning stages, so there will be more to come. To keep in the loop, stay tuned to this blog or do a periodic fly-by of my Upcoming Talks page.

I hope to see you at one or more of these presentations.

Scott

Thursday, March 13, 2014

A Concern about the Rule of Zero

The Rule of Zero, coined, as far as I know, by R. Martinho Fernandes in this blog post, is:
Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.
By "not have," Martinho really means "not declare", because all classes have destructors, one way or another, and the blog post makes clear that Martinho expects a non-resource-handling class to have the copying and moving behavior exhibited by its data members (and hence to have the corresponding functions, assuming such functionality is employed). If we revise the wording of the rule in accord with s/have/declare/g, we get:
Classes that declare custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not declare custom destructors, copy/move constructors or copy/move assignment operators.
This advice makes me a bit uncomfortable.

In concept, it's great. Morally, I'm on board. I agree that classes that don't manage resources should be designed so that the compiler-generated functions for copying, moving, and destruction do the right things. I'm just not sure that taking advantage of that by not declaring any of these functions is a good idea.

Consider a class Widget that doesn't do resource management. Per the Rule of Zero, it declares none of the five special functions covered by the rule. Further assume that its data members are both copyable and movable. Widget objects are therefore copyable and movable, too.
class Widget {
public:
  ...                // no dtor or copy or move functions
};
Wonderful. Life is good.

Now assume something in the software doesn't work the way it should. It could be a behavioral problem (i.e., your run-of-the-mill bug) or it could be a performance problem. Either way, debugging ensues. Let's assume that during debugging, it becomes convenient to temporarily add a destructor to do something like produce a log message for tracing purposes:
class Widget {
public:
  ~Widget();         // temporary destructor
  ...                // no copy or move functions
};
The addition of the destructor has the side effect of disabling generation of the move functions, but because Widget is copyable, all the code that used to generate moves will now generate copies. In other words, adding a destructor to the class has caused presumably-efficient moves to be silently replaced with presumably-less-efficient copies. That strikes me as the kind of thing that (1) is likely to surprise people and (2) could really complicate debugging. Hence my discomfort.

I'm inclined to recommend that a better way to rely on the compiler-generated copy and move functions is to expressly say that they do the right thing--to define them via =default:
class Widget {
public:
  Widget(const Widget&) = default;
  Widget(Widget&&) = default;

  Widget& operator=(const Widget&) = default;
  Widget& operator=(Widget&&) = default;

  ...
};
With this approach, the spirit of the Rule of Zero remains: classes that don't manage resources should be designed so that the compiler-generated functions for copying, moving, and destruction do the right things. But instead of expressing this by not declaring those functions, it's expressed by declaring them explicitly and equally explicitly opting in to the compiler-generated implementations.

What do you think? Does this advice make sense? Should the Rule of Zero perhaps be the Rule of the Five defaults?

Thanks,

Scott