Tuesday, February 18, 2014

Help me name my book

The book I'm currently working on is about the effective use of features new to C++11 and C++14. It covers nothing that's in C++98, other than brief descriptions where they're needed for context. The book consists of entirely new material; nothing is repeated from Effective C++, More Effective C++, or Effective STL. One of the questions I have to answer is what to call this book.

Originally, it was going to be called Effective C++11, but then I decided to cover both C++11 and C++14. My working title is Effective C++11/14, but I'm not terribly happy with that. First, there's no such thing as C++11/14. Second, I'm concerned that by 2015, a book with C++11 in the title will look outdated. On the other hand, I worry that if I call it Effective C++14, many people will assume that it has nothing in it for them if they're "only" using C++11.

An ideal title would convey these points:
  • The content is about the effective use of features new to C++11 and C++14. It doesn't rehash information about C++98, even if it continues to be valid. (For more on this, see my blog entry about the information in Effective C++, Third Edition in the post-C++98 era.)
  • The C++14 material was designed in from the outset, it wasn't just stapled onto a C++11 book as an afterthought.
  • The book isn't a new edition of Effective C++. It complements Effective C++, it doesn't supersede it.
Of course, there will be a description of the book's role and content in its marketing materials, but experience has shown that people often make assumptions about the content of books based on the title and author. Once they've made those assumptions, it generally takes a lot more than a couple of descriptive paragraphs to dislodge misconceptions. It's best for everybody if people's assumptions are correct at the outset.

My plan is to continue my tradition of using a short title that begins with "Effective", plus a longer subtitle. The title can't be "Effective C++," because that's a different book. Here are two possibilities:
  • Effective C++11/14: n Specific Ways to Improve Your Use of the Newest Versions of C++
  • Effective C++14: n Specific Ways to Improve Your Use of C++11 and C++14

What do you think? What should I call the book I'm supposed to be working on as I'm writing this blog entry? What title would be, you know, most effective? (It need not be one of the two I listed above.)



Tuesday, February 4, 2014

Status Report on Effective C++11/14

About a year ago, I blogged, "If everything falls into place the way I hope it will, there will be a book about 10 months from now. If. I'm not making any promises." Smart me: it's been 12 months, and there's still no book. In part, that's because I decided to expand the scope of the project to encompass C++14 as well as C++11. That required that I familiarize myself with C++14, which has only recently really settled down. Another factor is that writing the Items for the book has proved to be slower going than I expected. I thought my researching days were behind me, but I've spent many more days tracking down language details than I'd predicted.

But I've made progress. I have full drafts of 26 Items, and I have a candidate list of 25 more. Most of the candidate Items won't make the final cut, because it's looking like the book will end up with around 40 Items total. That's due to space limitations. My prior books have run up to around 90,000 words total (about 300 pages) , and that's the length limit I'm imposing on this one.I currently have about 54,000 words, so by that measure, I'm about 60% done. That's a high estimate of how much is complete, unfortunately, because feedback I've received on existing Items reveals that some require significant rework before they'll be ready to be reviewed again.

As things stand now, I'm thinking I should be done by the beginning of June. (Between now and then, writing the book is essentially my full-time job.) "Done" is a funny word, however, because it simply means I've declared my manuscript ready to publish. That's step one in a multi-step process that ultimately leads to printed and digital books. My document has to be translated from the format I use (MS Word) into its final forms (probably print PDF, digital PDF, ePub, and Kindle), and along the way it may get translated into XML as an intermediary format. I'll spare you the details, but suffice it to say that these translations will be largely custom-made for my book, and that means they'll take time to develop and verify. I won't be doing them myself, though I'll be quite involved in making sure they produce the proper output.

I'm hoping that digital versions of the book will be available this summer, but don't press me on exactly what "summer" means. Print books will probably take a bit longer, so call my hope for availability "late summer,"  where neither "late" nor "summer" is well-defined.

In case you're interested in a glimpse into the process of writing this book, I've made available two versions of the Item I finished writing just today, "Declare functions noexcept whenever possible."
  • A first draft with my comments on it. My usual approach to producing an Item is to write and edit it on-screen until it looks decent, then print it out and mark it up, and finally make the edits I've marked. I then print it again, mark it up again, and...rinse, lather, repeat. Generally, it takes about three iterations before I think I've got something ready for the next step, which is to make sure the code compiles. After fixing any simple coding errors, I forward the Item to outside reviewers for their feedback. If the code has errors that are serious enough to affect the content of the Item, I do the necessary rewrite, then fall back into the print/markup/edit loop.
  • The reviewable draft, i.e., the document I've just sent to some outside reviewers for their comments. In this case, that includes you. Feel free to email me your comments and suggestions for improvement, or post them as comments on this blog post.
At some point later, I'll post the current status of the table of contents. Given that I'm going to have to jettison a large number of Items in the current outline, I don't see the point in doing that now. I'll do it once I have a list that looks more stable.

And now, if you'll excuse me, I have a word processor waiting for me...


Monday, February 3, 2014

Capture Quirk in C++14

Consider this code, which is legal and has the same behavior in both C++11 and C++14:
  const int ci = 42;
  auto f = [ci]() mutable { std::cout << ci << '\n'; };
  f();      // prints 42
This captures the local variable ci by value, thus putting a copy of it inside f. What's interesting is that because ci is const, the copy of it is const, too. That means that attempting to modify the copy of ci inside f won't compile:
  const int ci = 42;
  auto f = [ci]() mutable
           { std::cout << ++ci << '\n'; };      // error! can't modify
                                                // copy of ci that's in f
I wrote about this a couple of years ago in my article, Appearing and Disappearing consts in C++.

Yawn, old news. I know. But C++14 has generalized lambda captures, which means that another way to capture ci by value is this:
  const int ci = 42;
  auto f = [ci = ci]() mutable                  // note revised capture mode
           { std::cout << ++ci << '\n'; };      // okay! copy of ci in f is non-const!
The spec for such captures says that the type of the variable being initialized (the left-hand ci) is determined by the rules used by auto, and auto ignores the constness of initializing expressions when a non-reference, non-pointer is being initialized. So when ci is captured by value using this syntax, the copy inside f isn't const. (This assumes that the lambda is mutable, as it is here. For an explanation of why, I'll again refer you to Appearing and Disappearing consts in C++.) So with C++14, we have two ways to capture a local variable by value: non-generalized and generalized. Non-generalized, which is valid in C++11 and C++14, retains the constness of the variable being captured in the type of the copy. Generalized, which is valid in C++14 only, discards the constness of the variable being captured in the type of the copy. To top things off, we have two syntaxes for non-generalized capture: implicit and explicit. Hence the choices for capturing ci by value are:
  const int ci = 42;
  auto f1 = [=]() mutable                      // non-generalized implicit copy
            { std::cout << ++ci << '\n'; };    // error! copy of ci in f is const

  auto f2 = [ci]() mutable                     // non-generalized explicit copy
            { std::cout << ++ci << '\n'; };    // error! copy of ci in f is const

  auto f3 = [ci = ci]() mutable                // generalized copy
            { std::cout << ++ci << '\n'; };    // fine, copy of ci in f is non-const
Personally, I was never wild about the const retention in non-generalized captures, so I'm pleased that in C++14, there's a way to work around it.


PS - For the terminally curious, the behavior I'm referring to is specified in 5.1.2/15 for non-generalized captures and 5.1.2/11 for generalized captures (in N3797, the current draft for C++14).