Guru of the Week and the Exceptional C++ Series

It’s time for me to pick up Guru of the Week (GotW) again in earnest, as part of work on revising my three Exceptional C++ books for today’s C++. Most Exceptional C++ Items are enhanced versions of GotW issues, after all, so the simplest and best place to start is with GotW. It’s also much easier to write (and read) one short piece at a time.

Last spring I wrote a few GotWs, but life got busy with the Standard C++ Foundation, isocpp.org, and C++14. I was also trying to figure out what reasonable tools to use to write new Items, since I wanted to publish the same Item on this blog and then in e-book and dead tree editions, all with a single source while maintaining a pleasing format. I’ve found a provisional promising tool (Word!) and format for that I’ll try out for now, and you’ll see it in the next GotW issue to be posted soon.

But a major issue was figuring out the right balance between updating existing GotW issues and writing new ones.

Here’s where I landed…

 

First, I’ve decided to keep and revise nearly all of my existing Items. This is not an obvious choice: As a counterexample, some authors have decided to not revise their existing books, but to write new books about C++11, for various reasons including that they expect the advice in the earlier books is still current. I think the latter is partly true, because of course the topics are still current and the code still compiles – C++11 has a great backward compatibility story with C++98.

However, when I looked through my own articles and Items, every single one I looked at had two qualities:

  • The topic was still current and useful, so it should still be covered. (With very rare exceptions like material discussing the now-removed export template feature.)
  • The code and discussion were addressed with C++98-era advice that is now dated and/or incomplete.

For example, nearly every GotW’s code should just naturally use auto and { } initialization. Most should use or actively discuss move semantics, lambdas, and other C++11 features. And it’s hard to write about existing features like virtual function overriding (as in GotW #5) without feeling something important is missing unless there’s also discussion of the way C++ has extended the existing feature, such as with override and final.

 

Second, I’ve decided not to target C++11 – rather, I’m going to write for C++14. Why would I do that, when C++ compilers [preemptive snarky remark: including my own team’s] are still catching up to C++11? For several good reasons:

  • C++14 is going to be current C++ soon. As of April, it’s now feature-complete, and the detailed technical specification should be frozen this fall or winter (leaving time for ISO ballots and “’14” publication). Compilers and libraries are already aggressively implementing it. I wouldn’t be surprised if we had multiple fully-conforming C++14 implementations by the end of next year.
  • C++14 is a small delta, a minor release aimed mainly at “completing C++11.” And it does complete C++11 well, to the point where as an author I really want to teach the complete story. I want to teach the complete “avoid writing new and delete” guidance that C++14 make_unique fully enables so that I can stop mumbling “except when you create a unique_ptr” as a special case. I want to write generic lambdas with C++14’s terse auto parameters that makes lambdas shorter to write and more flexible, and stop repeating parameter type names. I want to use C++14 move-capture in lambdas that makes them complete, and not feel obliged to talk about artificially putting objects on the heap and capturing shared_ptrs to them by value as a workaround for lack of move capture. And, in a few places where appropriate, I want to be free to use a few smaller C++14 tidbits like optional<T> that can affect interface design guidance now that they’re in the draft standard.

In addition, I’ve found that C++11/14 is changing my coding style, including my basic variable declaration style. I now think auto should be used consistently to declare local variables, even when you want to commit to a specific type(!) – this certainly surprised me, and likely will surprise you too, so I’ll cover that this year in a GotW and a recorded talk, no later than at C++ and Beyond later this year and possibly sooner.

 

I’ve converged on the above by updating the first dozen Exceptional C++ Items (in GotW order), trying out alternatives and seeing how well each one worked out. Those first dozen Items are now done and I’m pleased with the result, showing off auto and move and generic lambdas and mutexes/atomics and the new meanings of const and mutable and everything else, most of their code tested against various of the latest compilers, their advice updated to be current with current C++. And in every single GotW, no matter how short, it just felt right to:

  • keep the topic, because each topic is still as relevant and useful as ever;
  • revise the C++98 code and advice, because in every case both the code examples and the discussion was dated and/or incomplete, usually both; and
  • skip C++11 to write directly for the complete story in C++14 without apology, because it let me avoid digressions for workarounds not needed in C++14, which made the text cleaner and simpler.

As I’ve revised Items, I’ve found that some updates are small but pervasive, such as using auto. Others are extensive, with entire subsections completely rewritten, thrown out as no longer relevant, or newly added to cover essential new sides of the story in modern C++. For example, GotW #6 about const-correctness is now a two-parter, covering the new meanings of const and mutable. Watch for it soon.

 

A word about numbering and sequence: My plan is to update and post most GotWs in numerical order starting with GotW #1, but every so often we’ll jump forward to new high numbers (starting with #89) as I create ones that weren’t originally a GotW – a Sutter’s Mill magazine article that wasn’t originally published as a GotW, or a brand-new C++14 topic. So for example you might see a sequence like “… 23, 24, 91, 25, 26, …”. All GotWs will have substantial new material, but the newly minted high numbers will be entirely on brand-new topics that didn’t arise in C++98 or just weren’t covered in GotW form before. (The handful of GotWs I wrote last year will be renumbered as they’re folded into the original series, either as updates or with new numbers in the original sequence if they’re on completely new topics. )

 

I’ll start posting fresh C++11/14 GotWs in the next few days. As usual, I’ll first post a problem by itself to invite discussion about possible solutions, then after there’s been time for comments I’ll post my own solution and the next problem.

It’s kind of exciting to write “GotW14” – today’s C++ really does feel like a fresh new language.

I hope you enjoy them as much as I enjoy writing them.

23 thoughts on “Guru of the Week and the Exceptional C++ Series

  1. This is all great news and I look forward to reading the updates as they come available. I think updating for C++14 is a great idea … for selfish reasons. I recently started a new project and I am definitely finding C++11 is changing my coding style. I often reference GOTW for reminders of good techniques, so having them updated is going to be very good.

  2. @Rob:
    > The type is still there, albeit moved to the RHS; when you say “I always know the exact
    > type by looking at the right hand side of the assignment” does the same not apply with LHS
    > if you instead write the second example?

    Well yes, but the emphasis was supposed to be on “right hand side” – I always want to know the type by looking at the RHS. It really helps me when switching a lot between different languages, which I have to do many times a day (Javascript, PHP, Ruby, Python etc.).

    I have to agree that I found myself using auto a lot more than I thought I would – especially when dealing with iterators it saves so much time and I found myself to write better code thanks to having less of a penalty in time and effort when “doing things right”.

    One more note on one of your examples:

    auto iter = std::find_if( vertexRange.begin(), vertexRange.end(), []( const vertex& v ) { … } );

    I think in C++11 the preferred way of doing this is to use std::begin/std::end:

    auto iter = std::find_if(std::begin(vertexRange), std::end(vertexRange), []( const vertex& v ) { … } );

    In that specific example, like the general use of auto for local variables, pretty much a matter of style and taste. But after all C++ is the language of options, isn’t it? ;)

  3. @Michael I can only speak for myself, not Herb, but I don’t feel any benefit from your example:
    auto s1 = std::string(“We can do this to avoid const char*”);

    The type is still there, albeit moved to the RHS; when you say “I always know the exact type by looking at the right hand side of the assignment” does the same not apply with LHS if you instead write the second example?
    std::string s1 = “…”;

    My own use of `auto` has, despite early reservations, proliferated to any situation where the type can be inferred without loss of clarity:
    auto vertexRange = boost::vertices( graph );
    auto iter = std::find_if( vertexRange.begin(), vertexRange.end(), []( const vertex& v ) { … } );
    auto foo = std::make_shared( 42 );

    Incidentally I also use it anywhere a member function defined out-of-line has a return type scoped to the class:
    template typename foo::bar foo::get_bar() { … }
    template auto foo::get_bar() -> bar { … }

  4. I just can’t read of, I think Scott Mayers’s comment, that he always thinks of GotW as “Got You!”

  5. @herb
    I know, I just meant that you writing for C++14, instead of C++11 is a distinction without a difference for the most part… C++17 on the other hand :D

  6. @Herb:

    > In addition, I’ve found that C++11/14 is changing my coding style, including my basic variable declaration style. I
    > now think auto should be used consistently to declare local variables, even when you want to commit to a
    > specific type(!)

    Are talking about code like this?

    auto s1 = std::string(“We can do this to avoid const char*”);
    auto s2 = std::string{“or even that, still need to get used to the curly braces here”};
    auto s3 = std::string();
    auto s4 = “”s; // C++14?

    vs.

    std::string s1 = “…”;
    std::string s2 = “…”;
    std::string s3;
    std::string s4;

    Just curious, since I found myself writing code like this in my fully C++11 enabled projects lately. It feels natural to me, since I always know the exact type by looking at the right hand side of the assignment. If I look at s3/s4 right after working on C++98 code I don’t like it, while if I wrote Python code beforehand I do and appreciate how this states more explicitly that I want to create a default constructed std::string and store it in s3/s4.

    On a different note, will the assignment to s4 actually be possible in C++14 (N3531)?

    auto s4 = “I’m a std::string”s;
    std::cout << s4 << " is " << s4.length() << " chars long" << std::endl;

    Trip reports seem to suggest that it has been voted into the standard.

  7. @Tom
    Clang will soon be C++11 compliant and like I said C++14 is more like C++11.01 so I guess soon after C++14 youll have C++14 compilers.

  8. Re old vs. new: I want to replace existing public GotWs, not maintain two versions side by side, for several reasons:

    1. C++11 today, and C++14 very soon, *is* C++. GotW has always been about “current” C++, initially documenting the then-draft standard and tracking its changes (e.g., GotW #25 on auto_ptr was posted just before the meeting we knew auto_ptr would change, and the solution posted immediately after as the first documentation of the decision). I want to continue teaching current C++, and avoid disseminating dated material.

    2. I want to avoid ambiguity, to preempt questions of the form “is this the ‘real/current’ Gotw #xyz?” This was already a (minor) issue with the original public GotWs, because most of those were at least a little bit revised and expanded for the books, so the current version was actually in the books. This already caused some confusion when people saw the original GotWs and sent me comments already addressed in the updated book versions. I can imagine the same happening, only far more, with “original C++98 and revised C++14” versions of the same GotW floating around.

    So as I publish each revised GotW here, my plan is to leave the original one’s URL in place but replace it with a redirect to the current version of that same GotW. That will avoid two problems — people learning “old C++” material which I think is actively undesirable, and having “two current GotW #nnn” that I’ll have to disambiguate — as well as help me migrate to a unified site here without breaking links, which is important. (The current GotWs are on my old site, gotw.ca, which I’ve been meaning to migrate here for a few years, and this gives me the opportunity to gradually do that.)

    @JohnH: I won’t suggest people abuse ‘auto’. And I realize it’s a lightning-rod/bike-shed; witness the perennial debates about the same feature in other languages. Please withhold judgment until you see the presentation, then see if you find (all or just parts of) it are convincing. You might be convinced to try auto more, if not universally. I was.

    @nosenseetal: Well, C++11 and C++14 aren’t numbered as versions, just as publication years. And backward compatibility is nearly perfect — it’s just that there are better/simpler ways now in addition to the existing ones that still work just as well as they always have.

    @KCP, @EbilPhish: Yes, I’ll fold those in relatively early into the single sequence. I took them down because I didn’t want to cause needless confusion with their odd temporary numbering and different formatting.

    @Motti Lanzkron: Yes, ‘operator auto’ is being discussed this summer and there might be a paper. I might care about it enough to write it. :)

    @Ninja: Yeah, I still need to work on Effective Concurrency. No ETA, sorry. Writing is unpredictable when you have a day job. Writing individual book Items in the form of GotWs or magazine articles happens when I can make evening/weekend time and get inspired, and assembling and revising them as a book happens when I can make a bigger block of weekend/vacation time and get on a roll. That drives my editor batty too, because booksellers like to have lots of predictable lead notice, and often will advertise “coming” dates when you made the mistake of mentioning a ‘potential estimate’. Exceptional C++ Style and C++ Coding Standards had all their original articles written awaiting assembly and revision, and suddenly came together when I happened to have a month of relative downtime (both times it was in a December vacation) and could shut myself in and finish assembling and polishing them, so the end result was we went from “I don’t know when I’ll be done, I’m busy, leamme ‘lone” to “oh by the way it’s done, here’s the final camera-ready PDF attached, got a spare copyeditor to look at it before you send it to the printer’s?” in a few weeks. (I did let him know what was happening, so it wasn’t quite that exciting, but it was pretty fast.) All I can say is that essentially all the material for Effective Concurrency is already written as published articles, and they’re still current because they’re language-agnostic, so the question is mostly when the assembly and polishing block of time can appear. Clearly I’m putting XC++ first though, at least for now. :)

  9. Great to hear about C++14. I’m waiting for the day when it’ll get a proper module / module import system so that i’ll be free of headers and includes. I have faith.

  10. That is really good to hear. Though I suggest to keep the old pages also accessible (like a link at the solution opening the archived version, if they can’t be melt) for those still using old compilers. Or new ones that lagged behind with some of those features.

    It would also serve as comparison, to show side by side the advance of the language, and reflect the old ways that can be left behind.

  11. Great news! One thing comes to mind though. I know GotW is a well-known brand/trademark of sorts, but I can see problems ahead, trying to figure out wether this is this or this is that, i.e. the same name GotW#n but two completely different apples. Ok, one quick scan looking for auto would be enough to pick the fresh apple but what if I’m an crazy enough person and like to eat apples in the dark…

  12. Sorry, offtopic: The base font you use for the blog is really bad for my eyes. Did you ever think about to switch to a non-serif font in the future?

  13. Wonderful news. The updates to these books are sorely needed, in particular as many organisations lean on them heavily for their internal coding standards. I ran into this very problem this week as I scrabbled around grepping the web to be able to quote ‘What does Herb recommend *now*’ during a code review.

    ‘Multiple compilers’ will implement C++ 14 by the end of next year? Cool, I sincerely hope that includes MSVC! Here’s hoping you have some pleasant news for us at BUILD 2013. In the meantime can I add my voice to the chorus of thanks for continuing efforts in helping to shepherd C++ and its community Herb. Major kudos.

  14. Any chance you’ll post a solution for GotW #105 (Smart Pointers, Part 3)?

  15. “he handful of GotWs I wrote last year will be renumbered as they’re folded into the original series, either as updates or with new numbers in the original sequence if they’re on completely new topics. ”
    Backward compatibility = gone :P btw this C++11/14 is a bit like a joke…/ PR (like diff between AES128/256) it is more like C++11/11.01
    Other than that cool to hear you have find time to do new/ refresh GotW entries… they are pretty much classic C++ material. :)

Comments are closed.