Sunday, November 11, 2012

On the Superfluousness of std::move

During my presentation of "Universal References in C++11" at C++ and Beyond 2012, I gave the advice to apply std::move to rvalue reference parameters and std::forward to universal reference parameters.  In this post, I'll follow the convention I introduced in that talk of using RRef for "rvalue reference" and URef for "universal reference."

Shortly after I gave the advice mentioned above, an attendee asked what would happen if std::forward were applied to an RRef instead of std::move.  The question took me by surprise.  I was so accustomed to the RRef-implies-std::move and URef-implies-std::forward convention, I had not thought through the implications of other possibilities.  The answer I offered was that I wasn't sure what would happen, but I didn't really care, because even if using std::forward with an RRef would work, it would be unidiomatic and hence potentially confusing to readers of the code.

The question has since been repeated on stackoverflow, and I've also received it from attendees of other recent presentations I've given.  It's apparently one of those obvious questions I simply hadn't considered.  It's time I did.

std::move unconditionally casts its argument to an rvalue.  Its implementation is far from transparent, but the pseudocode is simple:
  
  // pseudocode for for std::move
  template<typename T>
  T&& std::move(T&& obj)
  { 
    return (T&&)obj;        // return obj as an rvalue
  }
std::forward is different.  It casts its argument, which is assumed to be a reference to a deduced type, to an rvalue only if the object to which the reference is bound is an rvalue. (Yes, that's a mouthful, but that's what std::forward does.)  Whether the object to which the reference is bound is an rvalue is determined by the deduced type.  If the deduced type is a reference, the referred-to object is an lvalue.  If the deduced type is a non-reference, the referred-to object is an rvalue.  (This explanation assumes a lot of background on how type deduction works for universal reference parameters, but that's covered in the talk as well as in its printed manifestations in Overload and at ISOcpp.org.)

As with std::move, std::forward's implementation is rather opaque, but the pseudocode isn't too bad:
  // pseudocode for for std::forward
  template<typename T>
  T&& std::forward(T&& obj)
  { 
    if (T is a reference)
      return (T&)obj;          // return obj as an lvalue 
    else
      return (T&&)obj;        // return obj as an rvalue 
  }
Even the pseudocode makes sense only when you understand that (1) if T is a reference, it will be an lvalue reference and (2) thanks to reference collapsing, std:forward's return type will turn into T& when T is an lvalue reference.  Again, this is covered in the talk and elsewhere.

Now we can answer the question of what would happen if you used std::forward on an RRef.  Consider a class Widget that offers a move constructor and that contains a std::string data member:
  class Widget {
  public:
    Widget(Widget&& rhs);       // move constructor
  
  private:
    std::string s;
  };
The way you're supposed to implement the move constructor is:
  Widget::Widget(Widget&& rhs)
  : s(std::move(rhs.s))
  {}
Per convention, std::move is applied to the RRef rhs when initializing the std:string.  If we used std::forward, the code would look like this:
  Widget::Widget(Widget&& rhs)
  : s(std::forward<std::string>(rhs.s)
  {}
You can't see it in the pseudocode for std::forward, but even though it's a function template, the functions it generates don't do type deduction.  Preventing such type deduction is one of the things that make std::forward's implementation less than transparent.  Because there is no type deduction with std::forward, the type argument T must be specified in the call.  In contrast, std::move does do type deduction, and that's why in the Widget move constructor, we say "std::move(rhs.s)", but "std::forward<std::string>(rhs.s)".

In the call "std::forward<std::string>(rhs.s)", the type std::string is a non-reference. As a result, std::forward returns its argument as an rvalue, which is exactly what std::move does.  That answers the original question.  If you apply std::forward to an rvalue reference instead of std::move, you get the same result. std::forward on an rvalue reference does the same thing as std::move.

Now, to be fully accurate, this assumes that you follow the rules and pass to std::forward the type of the RRef without its reference-qualifiers.  In the Widget constructor, for example, my analysis assumes that you pass std::forward<std::string>(rhs.s).  If you decide to be a rebel and write the call like this,
  std::forward<std::string&>(rhs.s)
rhs.s would be returned as an lvalue, which is not what std::move does. It also means that the std::string data member in Widget would be copy-initializd instead of move-initialized, which would defeat the purpose of writing a move constructor.

If you decide to be a smart aleck and write this,
  std::forward<std::string&&>(rhs.s)

the reference-collapsing rules will see that you get the same behavior as std::move, but with any luck, your team lead will shift you to development in straight C, where you'll have to content yourself with writing bizarre macros.

Oh, and if you make the mistake of writing the move constructor like this,
  Widget::Widget(Widget&& rhs)
  : s(std::forward<Widget>(rhs.s))
  {}
which, because I'm so used to passing std::forward the type of the function parameter, is what I did when I initially wrote this article,  you'll be casting one type (in this case, a std::string) to some other unrelated type (here, a Widget), and I can only hope the code won't compile.  I find the idea so upsetting, I'm not even going to submit it to a compiler.

Summary time:
  • If you use std::forward with an RRef instead of std::move, and if you pass the correct type to std::forward, the behavior will be the same as std::move.  In this sense, std::move is superfluous.
  • If you use std::forward instead of std::move, you have to pass a type, which opens the door to errors not possible with std::move.
  • Using std::forward requires more typing than std::move and yields source code with more syntactic noise.
  • Using std::forward on an RRef is contrary to established C++11 idiom and contrary to the design of move semantics and perfect forwarding.  It can work, sure, but it's still an anathema.
Scott

Friday, November 2, 2012

"Universal References in C++11" now online at ISOCpp.org

The October Overload article I blogged about earlier, "Universal References in C++11," is now available online at the spanking new ISOCpp.org website. In conjunction with my video presentation at Channel 9 on the same topic, this means you now have your choice of three different ways to experience my pitch for adding "universal reference" to the accepted C++ vocabulary:
  • Overload version: Monochrome PDF and, if you're a subscriber, hardcopy.
  • Channel 9 version: Video of me presenting the information, along with the original presentation materials.
  • ISOCpp.org version: HTML version with syntax-colored code examples and live hyperlinks.
I really think that the idea of universal references helps make C++11's new "&&" syntax a lot easier to understand. If you agree, please use this term and encourage others to do it, too.

Scott

Friday, October 26, 2012

The Standard works in Circular Ways

Rummaging around in the C++11 standard isn't all fun and games, but from time to time you come across true gems.  For example, this is from 2.14.7/1 in the standard:
The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t.
And this is from 18.2/9:
nullptr_t is defined as follows:
namespace std {
  typedef decltype(nullptr) nullptr_t;
}
So nullptr is of type nullptr_t, and nullptr_t is defined to be the type of nullptr.

Um, okay.

Scott

Tuesday, October 23, 2012

Video for "Adventures in Perfect Forwarding" Now Available

On Saturday, June 2, Facebook sponsored a one-day C++ conference and asked me (and others) to give a presentation.  I chose an abridged and updated version of a talk from C++ and Beyond 2011, "Adventures in Perfect Forwarding."  Judging by the dates on the comments below the video, it's been available since July, but I found out about it being online only today. (Apparently I don't have enough friends.)

The video is broken into two parts, each about 30 minutes long:
Due to technical difficulties at Facebook during the talk, some audio is missing and other audio is out of sync with the video.  My understanding is that these issues can't be addressed, so we have to live with the limitations of the recording.

Facebook does not appear to have made the presentation materials available, but you can grab them here (PDF).

I hope you enjoy this talk.

Scott

Thursday, October 18, 2012

Updated Release of "Effective C++ in an Embedded Environment"

In April 2010, I made the presentation materials for two of my training courses available for purchase. Purchasers get free updates for life. The first set of materials, An Overview of the New C++ (C++11), has since seen five update releases, and a sixth will occur sometime later this year. The other course, Effective C++ in an Embedded Environment, has not been revised. Until now. A new version has just been published, and if you have purchased these materials, you should have already been notified about how to download the new version.  If you have not (e.g., because you asked Artima, the publisher of these materials, not to send you email), Artima asks me to remind you that
You can log into Artima with the account you used to purchase the book, click on "Your Settings", and redownload anytime. If you've forgotten your password, you can get a reminder here.
It would be a mistake to interpret the greater frequency of updates for the C++11 materials as meaning that I pay less attention to the materials on using C++ in embedded systems.  I don't.   The simple fact is that C++11 was in a state of flux up until final standardization, and since then compilers have been adding increasing feature support, plus I've been learning more about the features in C++11 and how to use them.  There's been a lot happening in the C++11 world, and I've been working hard to keep my training materials current (while at the same time not bombarding you with updates).

The world of C++ in embedded systems has been stabler, and so have my materials devoted to that topic.  Even so, the changelog for the materials (available with your update) lists some five dozen changes affecting around 80 pages—about 25% of the total slides.  None of the revisions are earth-shattering, but a lot of little things have been fixed or clarified or otherwise improved. I have a strong incentive to keep these materials in as good a shape as I can: they're the ones I use myself.

I hope you enjoy the latest versions of my training materials on the use of C++ in embedded systems.  As always, you can download a free sample of the materials (the first 30 pages) from the materials' sales page.

Scott

Saturday, October 13, 2012

Copying Constructors in C++11

Today I read Martinho Fernandes' post, "Some pitfalls with forwarding constructors." What caught my attention was his claim that a forwarding constructor (i.e., a templatized constructor taking a universal reference) is a copy constructor.  "Can't be true," was my initial thought, because in the past it was true that it couldn't be true. But then I kicked myself.  "Crawl out of the 1990s," I told myself (meaning 1998, the year of the first C++ standard).  C++11 has new rules, and with new rules comes a new game.

Setting aside edge cases we need not fritter away time on, the copy constructor for a class C takes a parameter of type const C&.  If there is no such function declared in a class and such a function is needed (because it is used somewhere), it is automatically generated.  This is absolutely true in C++98 and is typically true in C++11, and the difference between absolutely and typically is not of interest here.  Where I'm going with this does not require acknowledging the nooks and crannies along the way.

In C++98, you could use a template to write what I called a "generalized copy constructor," and you did it like this:
class Widget {
public:
  template<typename T>
  Widget(const T&);
  // ...
};
The key thing to recognize was that this template, though it could be instantiated to yield the signature of a copy constructor, is itself not a copy constructor, and that means that the class does not declare one.  That being the case, if the copy constructor is needed, the compiler generates one as usual, because that's the rule: if there is no user-declared copy constructor (i.e., constructor taking a const Widget& parameter) and one is needed, the compiler generates one.  The fact that such a function could be generated from a user-declared template is irrelevant.

When the compiler sees a request to copy an object, it still has to consider the possibility of calling a template instantiation, but the template instantiation has the same signature as the implicitly-generated copy constructor, and (1) the copy constructor is a function (not a template function) and (2) when a function and template function are equally good matches for a function call, overloading resolution chooses the function.  The end result is that copy constructors can never be generated from templates.

To the best of my knowledge, all this remains true in C++11.

What changes in C++11 is the possibility of writing a generalized copy constructor taking a universal reference--a universal copy constructor:
class Widget {
public:
  template<typename T>
  Widget(T&&);        // now takes universal reference
  // ...
};
Consider now this code:
  Widget w;
  Widget wcopy = w;           // copy w to wcopy
This is a request to copy w. Widget has no copy constructor, so the compiler generates one with the default signature. The resulting class looks like this:
class Widget {
public:
  Widget(const Widget&);         // copy constructor (compiler-generated)  
  template<typename T>   
  Widget(T&&);        // universal copy constructor

  // ...
};
When the compiler see the request to copy w, it knows it can call the copy constructor, just like it could in C++98, but it also knows that it can instantiate the template. Unlike the C++98 template, however, this one lacks a const-qualification on its parameter, so the resulting instantiation also lacks one. After instantiation, the class effectively looks like this:
class Widget {
public:
  Widget(const Widget&);         // copy constructor (compiler-generated)  
  Widget(Widget&);               // instantiated template

  // ...
};
Overload resolution now kicks in to choose from these two candidate functions. (Technically, one is a template function, not a function, and to be really technical about it, it's a template specialization, not a template instantiation, but none of that matters here.)

The parameter to these functions would be the object being copied.  That's ww is not const.  A call to the compiler-generated copy constructor would require the addition of const to get an exact match, but the call to the instantiated template requires no such addition.  As a result, it's a better match.  The copy constructor will not be called to copy w.  Instead, the instantiated template will.

The situation changes if we copy a const Widget:
  const Widget cw;
  Widget cwcopy = cw;           // copy a const Widget
Now we're back in C++98-land. The compiler-generated copy constructor and the template instantiation have the same signature (both take const Widget& parameters), so the function wins.

At least that's how I view it.  gcc 4.7 agrees.  Given this program,
#include <iostream>

class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};

void endLine() { std::cout << '\n'; }

int main()
{
  Widget w;

  {
    std::cout << "Create Widget from Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(w);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = w; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {w}; endLine();
    endLine();
  }

  const Widget cw;

  {
    std::cout << "Create Widget from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(cw);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = cw; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {cw}; endLine();
    endLine();
  }
}
gcc 4.7 produces this output:
Create Widget from Widget:
  Direct init w/parens: Universal Widget ctor
  Copy init           : Universal Widget ctor
  Direct init w/braces: Universal Widget ctor

Create Widget from const Widget:
  Direct init w/parens: Widget copy ctor
  Copy init           : Widget copy ctor
  Direct init w/braces: Widget copy ctor
Nothing surprising there, but if I use auto to deduce the type of the copy, gcc's output changes. That is, this source code,
int main()
{
  Widget w;
  {
    std::cout << "Create auto from Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(w);   endLine();       // now using auto
    std::cout << "  Copy init           : ";   auto wcopy2 = w;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {w};  endLine();
    endLine();
  }

  const Widget cw;
  {
    std::cout << "Create auto from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(cw);   endLine();
    std::cout << "  Copy init           : ";   auto wcopy2 = cw;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {cw};  endLine();
    endLine();
  }
}
produces this output:
Create auto from Widget:
  Direct init w/parens: Universal Widget ctor
  Copy init           : Universal Widget ctor
  Direct init w/braces: Universal Widget ctor  Universal Widget ctor

Create auto from const Widget:
  Direct init w/parens: Widget copy ctor
  Copy init           : Widget copy ctor
  Direct init w/braces: Widget copy ctor  Universal Widget ctor
This is surprising. Where are those extra constructor calls coming from? (In a comment on my last post, Julain posted results for clang, which did not show such extra calls.)

I had a theory.  To test it, I added a move constructor to Widget,
class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }
  Widget(Widget&&) { std::cout << "Widget move ctor  "; }           // added this

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};
then reran the test (using auto-declared variables).  The revised results?
Create auto from Widget:
  Direct init w/parens: Universal Widget ctor
  Copy init           : Universal Widget ctor
  Direct init w/braces: Universal Widget ctor

Create auto from const Widget:
  Direct init w/parens: Widget copy ctor
  Copy init           : Widget copy ctor
  Direct init w/braces: Widget copy ctor
No extra constructor calls. Funky, no?
Some of the following analysis is incorrect, but rather than simply edit the post to remove the wrong information and replace it with correct information, I'll add comments like this.
gcc is making an extra call to the universal copy constructor only when I use brace initialization.  My theory is based on the observation that when brace initialization is used to initialize a std::initializer_list object, the values in the braced list are copied into a temporary rvalue array.  There are no std::initializer_list objects in my code, but let's suppose, for reasons I cannot fathom, that the use of auto in the above code somehow prompts gcc to treat a braced initializer as if it were being used with a std::initializer_list.
There are std::initializer_list objects in my code, because, as a prospective guideline for Effective C++11 puts it, "Remember that auto + {} == std::initializer_list." The statement
auto wcopy {w};
creates an object of type std::initializer_list<Widget>, not, as I had thought when I wrote the original post, an object of type Widget.
If that were the case, the to-be-copied Widget would be copied into the array, where it would be an rvalue that would then be moved into the object being initialized.  That is, given
auto wcopy {w};
w would be copied into an array, and a request would then be made to move this array element into wcopy. But in the code where I declare no move constructor, no move constructor can be generated, because I've declared a copy constructor, and if you declare a copy operation, no move operators are generated.  So in the code that requests a move of the rvalue in the array, the move is accomplished by calling a copy operation.

Because the object in the array is a copy of the actual initialization argument, it's not const, even if what it's a copy of is.  In this code,
const Widget cw;
auto cwcopy {cw};
though cw is const, the copy of cw in the array is not.  That means that when the compiler has to choose between the copy constructor (which takes a const Widget& parameter) and the instantiated universal copy constructor (which, in this case, takes a Widget& parameter), the universal copy constructor is the better match.

Remember, this is all a theory.  But it does explain the output from gcc.  In particular, it explains:
  • Why there is an extra call to a copying operation:  because the first copy operation copies the initializing object into the array, and the second one copies it from the array to the target of the initialization.
  • Why the extra call is to the universal copy constructor: because any cv qualifiers present on the initializing object are absent from the copy in the array, and the universal copy constructor is a better match than the conventional copy constructor for non-const objects.
  • Why the extra call goes away when I declare a move constructor: because then the move constructor can be called on the rvalue in the array, but calls to copy constructors and move constructors can be optimized away under certain conditions (which are fulfilled here).  Such call elision is generally not permitted for other functions, including the universal copy constructor.   Which means that when the move constructor is missing and cannot be generated, the universal constructor must be called, but when the move constructor is present, it need not be called.  
Are we having fun yet?

If my theory is correct, I think it identifies a bug in gcc, because, as far as I know, the only time the contents of a braced initializer list are copied into a temporary array is when they're being used with a std::initializer_list object.  (It may happen in calls to std::async and the variadic std::thread constructor, too, but I'm too lazy to look it up right now.)
I no longer believe that this is a bug in gcc, because gcc is doing exactly what I'd guessed:  initializing a std::initializer_list<Widget> object. I just didn't think it was supposed to.  Now I do.
Anyway, bottom line: in C++98, copy constructors could not be generated from templates, but in C++11, they can be, practically speaking.  At least that's my current understanding.  Thanks to Martinho Fernandes for his post that sent me down this particular rabbit hole.
Thanks also to Xeo for pointing out the error in my original post.
Scott

Friday, October 12, 2012

Posting C++ Code

I decided that if I'm going to be posting code, I might as well figure out how to make it look like code. In a comment on my last post, Nuno Barreiro's suggested I use SyntaxHighlighter, so I decided to give it a try.

Never in the history of software development has there been a tool with more explicit no-brains-are-required installation and usage tutorials.  My favorite is this one, because, really, how much more can you ask than for screen shots with arrows pointing where to click and "Click this" directives?  I threw caution to the wind and did exactly as I was told. Security be damned, I wanted my code to be syntax-highlighted, and I was in a hurry!

It didn't work.  The syntax of my code was not highlighted, and I got an error telling me that the brush I needed couldn't be found. An hour or so of googling and trial and error and more googling and more trial and more error ensued before I figured out that the name of the brush I needed was "c++", not "C++". That despite the fact that the documented brush name is "C++" and the name of the JavaScript file is shBrushCpp.js.  (Alias brush names are "cpp" and "c", both of which also work, but by the time I started playing around with the aliases, I was beyond noticing that the file name contained "Cpp", but the alias is "cpp".  My bad.)

To get code to display properly, you have to enter it in HTML mode (at least in Blogger, which is the platform I'm using), and you have to remember to transform all opening angle brackets ("<") into their fetching HTML equivalents ("&lt;"). I use Centricle.com's Encode/Decode HTML Entities page for that.

To get C++ code highlighting in Blogger, then (and I'm posting this here more for me than in the hope it might be useful to somebody else) you first blindly point, click, copy, and configure as per this page (initial setup) and this page (additional configuration). For each code fragment you want to appear in your blog, you:
  1. Write the code elsewhere, presumably where you can easily edit and test it. I use Emacs, but I've heard tell that there are other code and text editors.
  2. Transform the code into HTML-friendly form via something like the Encode/Decode HTML Entities page.
  3. Copy the transformed code into the HTML editor in Blogger.  Put said code into a pre block as follows:
<pre class="brush: c++">
Your code goes here
</pre>
In the words of technical support professionals everywhere, it works for me.

As a demonstration, here's some code I've been playing around with this evening.  The goal is to see which of several potential constructors is called when an object (an lvalue, if you insist on knowing) is copied. Try to predict what it will do before you feed it to your compiler. When I run it under gcc 4.7, I'm surprised by what I see.
#include <iostream>

class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};


void endLine() { std::cout << '\n'; }


int main()
{
  Widget w;

  {
    std::cout << "Create Widget from Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(w);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = w; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {w}; endLine();
    endLine();
  }


  {
    std::cout << "Create auto from Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(w);   endLine();
    std::cout << "  Copy init           : ";   auto wcopy2 = w;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {w};  endLine();
    endLine();
  }

  const Widget cw;

  {
    std::cout << "Create Widget from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   Widget wcopy1(cw);  endLine();
    std::cout << "  Copy init           : ";   Widget wcopy2 = cw; endLine();
    std::cout << "  Direct init w/braces: ";   Widget wcopy3 {cw}; endLine();
    endLine();
  }

  {
    std::cout << "Create auto from const Widget:\n";
    std::cout << "  Direct init w/parens: ";   auto wcopy1(cw);   endLine();
    std::cout << "  Copy init           : ";   auto wcopy2 = cw;  endLine();
    std::cout << "  Direct init w/braces: ";   auto wcopy3 {cw};  endLine();
    endLine();
  }
}
Update 10/17/12: Having run across this blog post, I also gave Google's Prettify a try. I don't like the result as well as that of SyntaxHighlighter, but judge for yourself.  Here's a prettified version of the Widget class above:
class Widget {
public:
  Widget(){};

  Widget(const Widget&) { std::cout << "Widget copy ctor  "; }

  template<typename T>
  Widget(const T&) { std::cout << "Generalized Widget copy ctor  "; }

  template<typename T>
  Widget(T&&) { std::cout << "Universal Widget ctor  "; }
};
Update 6/12/20: I removed support for SyntaxHighlighter and Google Prettify from the blog, because neither seems to be supported any longer. I did only cursory testing, but I'm hoping that the result will be that code examples in my blog posts continue to look like code, except they won't be syntax-highlighted.

Thursday, October 11, 2012

Parameter Types in Constructors

[This is the first time I've tried to include code fragments in a blog post, and let's just say I was surprised at how badly Blogger deals with them.  I apologize for any formatting problems, and I welcome suggestions on how to get Blogger to swallow code displays without throwing a fit.]


I recently went through Sumant Tambe's presentation materials from his Silicon Valley Code Camp presentation, "C++11 Idioms."  He argues that an emerging idiom is to pass arguments to constructors by value, because this takes advantage of move opportunities when they are available.  I was surprised to read about this emerging idiom, in part because I had not heard of it (I'm supposed to be clued in about this kind of stuff) and in part because it runs contrary to my own thinking on the subject, which is to use perfect forwarding. 

His presentation goes on to discuss the general problem of efficient parameter passing, based on a trio of blog posts by










Suppose I have a Widget class with a std::string data member.  In C++98, I'd initialize it like this:
class Widget1 {
public:
  Widget1(const std::string& n): name(n) {}

private:
  std::string name;
};
The problem here is that if an rvalue is passed to the Widget1 constructor, name is copy-initialized from n instead of being move-initialized.  That's easy to fix using perfect forwarding, which is designed to optimize this kind of thing:
class Widget2 {
public:
  template <typename T>
  Widget2(T&& n): name(std::forward<T>(n)) {}

private:
  std::string name;
};
No muss, no fuss, no enable_if, no testing for whether the argument passed to n was an rvalue--none of that stuff.  Very nice.

But let's suppose there's another way to initialize a Widget.  Instead of passing a name, we can pass an ID number, and the name can be looked up from the ID number.  In C++98, adding this would be trivial:
class Widget3 {
public:
  Widget3(const std::string& n): name(n) {}
  Widget3(int id): name(findNameFromID(id)) {}

private:
  std::string name;
};
Adding this to the version of Widget with the perfect forwarding constructor, however, leads to grief.  But not immediately. The class will compile without any trouble, and simple tests will work as expected:
class Widget4 {
public:
  template <typename T>
  Widget4(T&& n): name(std::forward<T>(n)) { std::cout << "T&&\n"; }
  Widget4(int id): name(findName(id)) { std::cout << "int\n"; }

private:
  std::string name;
};

Widget4 w1("Hello");      // calls perfect forwarding ctor
Widget4 w2(22);           // calls int constructor
But slightly trickier tests fail.  For example, if the type of the passed ID isn't exactly int--e.g., a long or a short or an unsigned--the perfect forwarding constructor is a better match, and the code will try to initialize a std::string with a numerical value.  This makes no sense, and the compiler will exhibit no reluctance in telling you that.  Given
Widget4 w3(22L);          // pass a long
gcc 4.7 says this:
ctors.cpp: In instantiation of 'Widget4(long int &&)':
ctors.cpp:40:18:   required from here
ctors.cpp:18:42: error: invalid conversion from 'long int' to 'const char *' [-
    fpermissive]

basic_string.h:487:7: error: init. arg 1 of 'basic_string<
        char; _Traits = char_traits<char>; _Alloc = allocator<char>, _Traits
      , _Alloc
    >::basic_string(
        const char; _Traits = char_traits<char>; _Alloc = allocator<char> *
      , const _Alloc &
    )' [-fpermissive]
In file included from c:\users\scott\apps\mingw\bin\../lib/gcc/i686-pc-
    mingw32/4.7.0/../../../../include/c++/4.7.0/string:54:0,
from ctors.cpp:1
The fundamental problem is that perfect forwarding and overloading make very bad bedfellows, because perfect forwarding functions want to take everything. They're the greediest functions in C++.

To curb their avarice, you have to limit the conditions under which they can be instantiated, and that's where enable_if comes in.  And where enable_if comes in, any semblance of beauty leaves.  For example, if you'd like to disable the perfect forwarding template for integral types (thus allowing the int overload to handle those types), you could code it this way:
class Widget5 {
public:
  template <typename T>
  Widget5(T&& n, typename std::enable_if<!std::is_integral<T>::value>::type* = 0)
    : name(std::forward<T>(n)) { std::cout << "T&&\n"; }
  Widget5(int id): name(findName(id)) { std::cout << "int\n"; }

private:
  std::string name;
};
This code behaves as we'd like, assuming (sigh) we'd like to treat a char as a number:
  Widget5 w3a("Sally");           // calls perfect fowarding ctor
  Widget5 w3b(44);                // calls int ctor
  Widget5 w3c(44L);               // calls int ctor
  Widget5 w3d((short)44);         // calls int ctor
  Widget5 w3e('x');               // calls int ctor
If more constructor overloads are added, or if the constraints on when the perfect forwarding constructor is applicable become more complicated, the enable_if-related code can become, er, unpleasant. Such unpleasantness is presumably the noise that Sumant Tambe refers to when he rejects perfect forwarding.

In those cases, I think his preferred solution to the problem of declaring constructor parameters--take everything by value--is reasonable.   The generated code isn't quite as efficient as you'd get from perfect forwarding, but the overloading rules are a lot easier to understand, and the resulting code is easier to both read and write.

I still think that perfect forwarding is the language tool you should prefer when you need to write constructors and similar functions (e.g., setters) that simply shuttle values from one place to another.  That's what it's designed for.  If you need to overload such functions, however, things get very messy very quickly, and except in the most demanding of performance-sensitive applications and libraries, I think it's reasonable to fall back on pass-by-value as the parameter-passing mechanism.

But these are still early days in C++11 programming, and we're all still learning.  I welcome your thoughts on how to declare constructor parameters, the proper role of perfect forwarding, and the wisdom of passing parameters by value.

Scott

Tuesday, October 9, 2012

Video for "Universal References in C++11" Now Available

A couple of days ago, I blogged that my article on "Universal References" had been published by Overload, and I said a video of me presenting this topic at C++ and Beyond would soon be available.  Soon has become now. Servers are standing by, and on-demand viewing is available at Channel 9.  Many thanks to Charles Torre and to Microsoft for recording and hosting the presentation. I hope you like it and find it useful.  If you do, please tell others about it, because I'm trying to inject the term universal reference into the C++ vocabulary, and I can't do it alone.

Scott

Saturday, October 6, 2012

New Article: "Universal References in C++11"

One of the most difficult aspects of C++11 for me to wrap my head around was the meaning of "T&&" in type declarations.  “It means rvalue reference,” I was told, and that was fine until I was also told that in some cases, it actually means lvalue reference.  I fought with this seeming contradiction for a couple of years before my head cleared and I decided that we need to distinguish declarations for rvalue references from declarations for things that look like rvalue references, but may not be.  I call these latter things universal references.  I hope the term catches on, because I think it makes the matter a lot easier to understand.

I gave a talk on universal references at this year's C++ and Beyond, and a video of that talk should go live sometime this month.  (I'll let you know when.)  I also wrote an article on the topic for ACCU's Overload, and the issue with the article (PDF) has just been published.  This is from the beginning of that article:
Given that rvalue references are declared using “&&”, it seems reasonable to assume that the presence of “&&” in a type declaration indicates an rvalue reference. That is not the case:
Widget&& var1 = someWidget;       // here, “&&” means rvalue reference

auto&& var2 = var1;               // here, “&&” does not mean rvalue reference

template<typename T>
void f(std::vector<T>&& param);   // here, “&&” means rvalue reference

template<typename T>
void f(T&& param);                // here, “&&” does not mean rvalue reference
In this article, I describe the two meanings of “&&” in type declarations, explain how to tell them apart, and introduce new terminology that makes it possible to unambiguously communicate which meaning of “&&” is intended. Distinguishing the different meanings is important, because if you think “rvalue reference” whenever you see “&&” in a type declaration, you’ll misread a lot of C++11 code.
I hope you find the article both interesting and useful.

Scott

Monday, October 1, 2012

The Projucer

A lot of uninvited stuff shows up in my electronic mailbox. There's spam, sure, plus my share of links, stories, and pictures from friends and family members who are more easily entertained than I am.  I also get questions and comments and links to C++- and software-related things people think---or hope---I might be interested in. I skip a lot of the "entertainment" I get from friends and family (none of whom read this blog, so I'm not worried about offending them), but in the realm of C++, I look at everything I get, because it's part of my job as a C++ consultant. Most of the stuff I see I dismiss without action, because I don't think it's interesting or I don't see how it's useful or I simply don't have time to really analyze and pursue it.  There are, after all, only so many hours in a day.

Julian Storer
(unless he's using
a picture of
somebody else)
Every once in a while, something piques my interest, and not always for the reason the sender imagines.  Such was the case about three weeks ago, when I got a message from Julian Storer. He wrote (with minor editing and link addition on my part):
For the last decade I've been running a big C++ cross-platform toolkit called JUCE. Won't attempt to describe it in this email - there's plenty of info about it on my website if you want to learn more.

I've just been making some announcements about a new tool that I'm aiming to release soon, and being proud of what I've managed to cook-up, I thought it'd be worth pestering some of my C++ guru heros to have a look at it. It's something that nobody's managed to do in C++ before, so I think you'll probably find it interesting!

The TL;DR is: I've built an IDE that uses Clang and the LLVM JIT engine to provide real-time interactive execution of C++ GUI code, and to allow GUI editing by automatic refactoring of user-code... Hard to sum it up in a sentence, but if you saw the Bret Victor demo that everyone was talking about a few months ago, you'll get the gist - he
was showing off interactive javascript, and I've managed to do the same trick in C++.

Hope you can spare 10 mins to check it out!
I did check it out, and not just because he called me a C++ guru hero. Though I had not watched all of  Bret Victor's demo, I had watched part of it, so I had some idea what was involved, and the idea that something similar could be done for C++ intrigued me.  Also, when people tell me they have done something in C++ that nobody has done before, that tends to catch my attention. Most important, at the time I was trying to figure out what to do with Julian's email, I had much more pressing things to work on that I didn't want to attack yet, so I needed a way to tell myself I was working without actually, you know, working.  So I toddled over to the screencast Julian had put together and invested the six minutes and thirty-six seconds it runs.

It's a nifty demo, but the application area is GUI development, and that's not really an area I know a lot about.  So when he ran the GUI from the compiled application, changed the application source code, then showed how the GUI updated itself, I was impressed with what must be happening behind the scenes, but I didn't have to hold onto my hat, nor was I concerned that my socks would be knocked off.  And when he modified the running GUI and some literals changed in the source code, I thought it was, well, nice. But then I saw something that made me replay that part of the video several times.  Not only did the literals in the source code change when he moved a GUI widget around, he was also able to have new statements added to the source code by interactively editing the running GUI.  He was editing the program source code through the GUI.

Maybe this is old news.  Maybe Visual Studio and Eclipse and various other IDEs for GUI development allow you to create and edit source code via both text (traditional source code) and generated GUI (arguably an alternative form of source code).  As I said, I'm not a GUI development guy, so I have no idea what the state of the art in this area is.  What I do know is that Julian's demo is consistent with the idea that there is no such thing as canonical source code.  C++ text is source code, of course, but there's no reason that the GUI generated from that source code can't be viewed as source code, too.  Since they're both source code, it makes sense that the underlying program can be edited through either.  One could argue that each representation of the program (C++ text and displayed GUI) is simply a view of that program, and the program itself is something more fundamental--something more abstract that transcends the concrete syntax and semantics of whatever view is used to see and manipulate it.

I'd like to believe that this is a reasonable argument, because, in essence, this was the topic of my PhD research many years ago.  My dissertation, Representing Software Systems in Multiple-View Development Environments, explored how one could represent programs such that they could be viewed and edited through any of a variety of concrete syntaxes ("programming languages").  Let me save you the trouble of reading my dissertation by summarizing my conclusion: It's hard.

I'm guessing that Julian was not expecting that his demo would remind me of the research I was pursuing over 20 years ago, but it did.  And that's why I'm blogging about it. Besides, as far as I know, he has done something in C++ that nobody has done before, and groundbreakers like that deserve encouragement. If you're wise in the ways of GUI development with C++, I encourage you to watch Julian's screencast and offer him feedback to help him continue his work.  I'm sure he'd be pleased to hear from you.

Scott

Save money! Expand your library! Win my bits!

It seems that the marketing department at Addison-Wesley has been working overtime, and one of the plots they hatched to lure you to their web site, where they're offering free shipping (within the USA) and a 30% discount if you buy one C++ book and 40% if you buy two or more, is a chance to win a free copy of the digital bundle of my three C++ books.  They even sent me this snazzy graphic for you to click on:
Actually, they sent me three graphics, so you can click on these, too, if you want to:

I'm sure that high-performance server software is standing by to count your clicks and whisk you to the land of irresistible C++ discounts.

To get the full discount, be sure to use the discount code "CPLUSPLUS".

Many of Addison-Wesley's recent C++ titles are introductory, and it's been so long since I was in need of that kind of book, I don't offer recommendations on them, though certainly many of the horses in the Addison-Wesley stable have excellent reputations.  One book I have looked at and strongly recommend is Nicolai M. Josuttis' updated-for-C++11 second edition of The C++ Standard Library.  Getting 30% or 40% off that book (or book+PDF combo) would certainly be nice. And frankly, if you don't yet own a copy of C++ Templates: The Complete Guide (by Nicolai M. Josuttis (who at this point should be sending me kickbacks--but, alas, isn't) and David Vandevoorde), this would be a good time to fill that hole in your library. 

Happy shopping, and good luck with the drawing to win the combined bits of my books. I hope it goes without saying that you don't need to buy anything to get a chance to win the digital versions of my books, but in case it doesn't, you don't need to buy anything to get a chance to win the digital versions of my books. So sign up!

Scott

PS - My mole inside AW whispers, "We are advertising this promotion as applying only to C++ titles, but it works for any set of titles from InformIT." So if you want to scratch that Scala itch that's been bugging you or you want to combine your buying power with that of colleagues who use--gasp!--other languages, now's your chance.

Wednesday, September 19, 2012

"Ask Us Anything!" Session from C&B 2012 now live

The final part of each C++ and Beyond is always the wide-open "Ask Us Anything!" Q&A session. Charles Torre from Microsoft's Channel 9 was there with video equipment in hand (okay, most was on the floor, and the camera itself was on a tripod, but you know what I mean), and his recording is now available.  Andrei, Herb, and I hope you enjoy it.

Scott

Saturday, August 25, 2012

C++ & Beyond Interview with me, Herb, and Andrei

At the end of the second day of C++ and Beyond, Charles Torre of Channel 9 corralled me, Herb Sutter, and Andrei Alexandrescu and pelted us with questions, some from him, others from Channel 9 viewers.  The interview is now online, the first of several videos associated with this year's C&B that will be rolled out on an ongoing basis.

Enjoy!

Scott

Tuesday, July 31, 2012

C&B 2012 Registration Ends Tomorrow!

Registration for C++ and Beyond 2012 ends tomorrow (Wednesday) at 11:55PM Eastern Time--roughly 36 hours from now.   For the third year in a row in this unique conference's three-year history, we've set a new attendance record, but there are still some spots available for this limited-enrollment event. 

Perhaps one reason for the unprecedented interest is the unprecedented amount of technical material we'll be presenting, much of it announced only recently.  We even extended the schedule for the first two conference days to make room for new content.  If you haven't been following the C&B blog, you may be interested in these posts from the past week and a half:
  • Writing Fast Code, which describes a new double-length session (three hours total) that Andrei Alexandrescu will be presenting based, in part, on the work he's been doing at Facebook to optimize the processing of, well, lots, of data. This is not theoretical it-should-run-faster-if-we-do-this kind of stuff, it's the result of countless hours trying things out and seeing what actually works.  For performance-oriented C++ developers, it can't get more practical than this.
  • A Special Announcement by Herb Sutter that gives C&B attendees a sneak preview of and an opportunity to help shape the initial rollout of a project that will be a boon to the entire C++ community.  As Herb clarified in a comment below his post, this project will be free and available to everybody when it goes live, but Herb needs a limited group of active and experienced C++ developers from whom to solicit feedback and engage in active discussion at this point in the project's creation, and C&B 2012 attendees will be part of that group.
  • More C&B than ever!, which describes how each year's C&B has scheduled more time for technical content than the year before.
Those are just the most recent posts.  For all the C&B-related info, check out the full blog history.

This isn't the C&B blog, however, it's my blog, so I'll remind you of the talks I'll be giving at C&B:
Having just finished the materials for these presentations, I can say I'm quite excited about them.  I think they'll help make it easier to use some of the new features in C++11 to greatest effect, while at the same time avoiding some of the potential pitfalls that accompany those features.

I hope to see you in Asheville, NC, next week.

Scott

Thursday, June 21, 2012

Final C&B Talk Announced

I just announced the final talk I'll be giving at this year's C++ and Beyond. It's Secrets of the C++11 Threading API.  Like my other talks, it's a new presentation covering new information I've never written, blogged, or spoken about before. (Okay, there may be some tiny overlap.  For example, in my Effective C++11 talk, I'm going to offer a more detailed analysis of the issues I raised in my blog post, std::string, SSO, and Move Semantics.)

The full slate of talks I'll be giving at C&B in August is:
In addition, I'll be participating in panel discussions and Q&A sessions with Herb Sutter and Andrei Alexandrescu on these topics:
For the talks Andrei and Herb will be giving, check out the C&B schedule. I think you'll find that the mix of talks this year is especially compelling, even by C&B standards.

Registration for C++ and Beyond continues through the end of July, but we're nearly 3/4th full, and once all the seats are gone, they're gone.  In addition, the discounted room rate for C&B attendees expires on July 6, so if you're interested in being part of the premier C++ event of 2012 (at least among those being held in Asheville, NC, in August :-}), I encourage you to sign up sooner rather than later.

Scott

Thursday, June 14, 2012

35% Discount Code for my Digital Book Bundle

Today I got email from my publisher regarding the bundled electronic versions of my books:
Only informIT.com offers this collection in both PDF and ePub formats, together for one price. PRE-ORDER TODAY and SAVE 35% off the list price.
Enter the coupon code MEYERS8627 during checkout to receive your discount. Offer expires June 21, 2012.
The list price of the bundle is $95.99, but, from what I can tell, the "normal" pre-order price is $76.79.  The email says that with the code, the price drops to $62.40.

I don't know if I'm supposed to share this coupon code with you, but the email didn't say I shouldn't, so here you go :-)

In my original post about this digital book bundle, I noted that I had not had a chance to review the product, and that's still the case.  (They tell me I'll get a copy once they're sure it's ready to ship, which I think is quite reasonable.)  I've also not tested the discount code mentioned above.  But I have no reason to think that the bundle is anything less than it's advertised to be, nor do I have a reason to doubt the authenticity of the coupon code. 

If you're interested in having electronic copies of my books for only about $20 each, this looks like a good way to get them.

Scott

PS - My wife suggests you buy as many copies as you can afford.  My editor wonders whether it'd really be such a hardship if you were to buy a few more than you can afford :-)

Wednesday, June 6, 2012

New Digital Bundle of my Books

I recently received this message:
Hi Scott,

I was looking through the books at InformIT.com and was checking to see if the promotion for buying all of your Effective C++ books together was still active and found this instead:


Are those updated versions of your books, or is that one SKU for all three existing books in that series?
I replied:
This is a single SKU for digital editions of all my existing books.  The content of the books is the same as the current editions of the printed books. I was not actually aware that this SKU had been put online, though I knew it was in the planning stages.
Shortly thereafter, I got mail from my publisher:
Your eBook digital collection is now available for pre-order. You can feel free to start pointing folks to http://www.informit.com/store/product.aspx?isbn=0133068625 now!
Consider yourselves pointed.

My books have been available in PDF for over three years (per this post from Feburary 2009), but, as far as I know, this is the first time they've been made available as a bundle of all three books in both PDF and ePub formats. I have not yet had a chance to examine this bundle myself (the author is always the last to know...), but when I announced the PDF versions in February 2009, I wrote:
[The PDFs are] DRM-free and chock-full of linked navigation in all the ways I believe you have a right to expect: tables of contents, indices, cross-references, URLs, mailtos, the whole nine yards.
To the best of my knowledge, all those features are still present.  For all I know, so are a whole bunch more.  Once I get my hands on the digital bundle and take a look at it, I'll let you know for sure. 

Scott

 

Monday, May 28, 2012

Final Week for Early-Bird Registration for C++ and Beyond

This is the final week for Early-Bird (i.e., discounted) registration for C++ and Beyond, the C++ conference-only-better event organized and put on by me, Herb Sutter, and Andrei Alexandrescu. Among the topics we'll address in our technical sessions are "universal references" in C++11 (a term I'll introduce, define, and, I hope motivate), using C++11 features to write error-resilient code, how new C++11 meanings for longstanding keywords affect concurrent and parallel code, and how to convince your colleagues to improve their software development behavior.  Additional topics are listed on the C&B 2012 Schedule Page, and there are more to come.

Every year I say the same thing about C&B, but every year I honestly believe it:  the coming C&B looks to be the best one ever. It's still the only C++ event featuring limited attendance; all-new presentations by me, Herb, and Andrei; and communal breakfasts and lunches as one of many characteristics designed to maximize the opportunity for you to talk not just with us, but also with one another.  In a year with more C++ events than probably any since the turn of the century, C++ and Beyond continues to distinguish itself as an event focusing not just on top-notch content, but also on face time with the people who developed the content and with the leading developers who will apply it.

During the Early Bird period, registration is discounted 10% for both individual and group registrations.  Group registrations (three or more) get an additional 10% off for being a group, so for the remainder of this week (i.e., through Friday), the discounts are effectively 10% for individuals and 20% for members of groups.  That's a savings of literally hundreds of dollars per registration.

Early-Bird registration won't be extended, so if you'd like to be part of C++ and Beyond 2012 (I'd certainly love to see you there), I encourage you to register no later than Friday.

Scott

Friday, April 27, 2012

Josuttis 2E has arrived!

For C++98, the standard everyday reference work for the C++ standard library was Nicolai M. Josuttis' The C++ Standard Library.  His updated version for C++11 has been eagerly anticipated, and I was pleased to receive my copy yesterday.

I was confident that the new edition would be a worthy successor to its predecessor, but I have this whole Trust-and-Verify mentality, so I forced myself to withhold judgement until I'd had a chance to check the book's content.  I wasn't disappointed.  Based on skipping around and reading here and there (primarily about functionality new to C++11, including emplacement functions, forward_list, random numbers, tuples, async, and the atomics API, not to mention an overview of new C++11 core language features, e.g., lambda expressions, rvalue references, constexpr, and more), the second edition of The C++ Standard Library looks to be to C++11 what the first edition was to C++98:  the first place to go for a readable and insightful summary of the C++ standard library.  Language lawyers will still turn to the C++ Standard itself, of course, and Josuttis' new book doesn't cover every nuance of library interfaces any more than the first edition did, but note my use of the word readable in my description of his presentation.  The Standard is definitive, but it's not readable.  Josuttis' book is readable, and, for most people most of the time, as good as definitive. I make my living studying the arcania of C++, but when I'm coding, I turn to Josuttis when I can and the Standard only when I must.

Interestingly, the physical size of the new book is no larger than the original edition, even though the standard library has become a lot bigger.  The new book has 300 more pages, however.  (Exactly 300.  The final page number in the first edition is 799, and the final page number in the new version is 1099.  How he managed that, I don't know, but it's a neat trick.)

[The following information about electronic editions has been revised since my original post.]
In terms of electronic editions, the book is available in PDF and ePub, plus there is an edition for Kindle. This information is courtesy of comments readers left on this blog entry, and I am grateful to them for it.

I encourage you to consider buying your own copy of the new edition of The C++ Standard Library.  Having it close at hand was indispensable for C++98 programming, and I think that having it close at hand for C++11 programming will be just as important.

Scott

Tuesday, April 24, 2012

Information on the C++11 Memory Model

I've been receiving a number of inquiries about where to turn for information about the C++11 memory model (technically the memory consistency model).  Having prepared and given a talk on the topic at last year's C++ and Beyond, I can tell you that the C++11 memory model is one of the most technically challenging topics I've ever tried to master. The good news is that if your goal is simply to write well-behaved multithreaded programs, you don't need to know any of the details of the memory model.  All you need to remember is to avoid data races in your programs, and the simplest way to do that is to follow the advice that multithreaded developers have been following for years:  access shared mutable data only when you know you have exclusive access to it, typically by acquiring a mutex before the access and releasing the mutex after the access. C++11 offers RAII classes to automate the release part of this protocol (std::lock_guard and std::unique_lock), so this is easier than ever to do. In C++11, you can also use atomic data types (e.g., std::atomic<bool>) to ensure exclusive access with often greater efficiency, but conceptually these are just data types where, on each access, C++ itself handles the moral equivalent of locking and unlocking the appropriate mutex.  (In practice, special machine instructions that avoid the need for mutexes are typically employed.) So, as I said, if your interest in the C++11 memory model is to know how to write threaded programs that will run correctly, you can essentially ignore the model itself.

If, on the other hand, you really want to understand the memory model, you have your work cut out for you.  Under no conditions should you start with the C++11 Standard!  Without the proper protective gear in place, that thing could maim you for life. Instead, I suggest you start with Anthony Williams' book, C++ Concurrency in Action.  Chapter 5 has the most comprehensible description of the C++11 memory model I have seen, and in fact it's the only one I know of that points out that C++11 actually offers three different consistency models:  sequential consistency, acquire-release consistency, and relaxed consistency.  (That alone should give you some idea of what you're in for if you decide to delve into this topic.) I own Williams' book in both electronic and paper form, and I think it's not just the best current treatment of C++11's threading facilities (including, but not limited to, the memory  model), it's likely to remain the best for some time to come.

Sources that complement Williams' coverage include the following.  Note that anything published before September 2011 may differ from the final C++11 memory model, and the longer the time before September 2011, the higher the likelihood of divergence.
Good luck!
Scott

Tuesday, April 10, 2012

std::string, SSO, and Move Semantics

I'm becoming increasingly concerned that C++11's support for move semantics is leading some people to conclude that we no longer have to pay as much attention to the cost of copying objects as we used to.  "Many copies will silently become moves," they exclaim, "and moves are cheap!" Such reasoning is invalid in a number of ways.

First, not all copy requests can be replaced by moves.  Only copy requests for rvalues are eligible for the optimization.  Second, not all types support move operations that are more efficient than copying operations.  An example is a std::array<double, 1000>.  Third, even types that support efficient move operations may support them only some of the time.  Case in point: std::string.  It supports moves, but in cases where std::string is implemented using SSO (the small string optimization), small strings are just as expensive to move as to copy!

What it means to be "small" is up to the implementation.  Unless I'm misreading the source files, std::strings with a capacity of up to 15 are "small" in Visual C++ 11 beta, so std::string objects of up to that capacity will not benefit when copies become moves.  (The SSO buffer size seems to be hardwired to be 16 bytes in VC11, so the maximum capacity of a std::wstring that fits in the SSO buffer is smaller:  7 characters.)

gcc 4.7 seems to continue to use reference-counting instead of SSO for its std::string implementation.  This is non-conforming in C++11 (reference-counting may no longer be used for std::string), and it looks like gcc is aware that it must be changed. However, gcc 4.7 offers the non-standard __versa_string with a std::basic_string-compatible interface (other than the name of the template and the namespace in which it's located), and __versa_string offers the SSO.  In this case, the maximum capacity of "small" strings seems to be hardwired to 15 characters (not bytes).

While googling around for a good page to link to for the term "small string optimization" above, I came across John Ahlgren's blog entry of March 30 on how SSO interacts with move semantics.  He refers to the fact that short strings with the SSO move more slowly than longer strings as the "small string deterioration" :-)

Scott

Thursday, April 5, 2012

C++11 is Almost Here for Real!

This entry is the first under a slightly expanded charter for this blog.  Until now, I've restricted blog entries to announcements about my professional activities.  Hereafter, entries will simply be related to my professional activities and interests. The difference is subtle, and, in all likelihood, you will rarely notice it.



At the beginning of my Overview of C++11, I show a simple program to compute the most common words in a set of input files.  I write the program once using "old" C++ (i.e., standard C++98/03), then again using features from C++11. 

In 2009, when I first published the C++11 program (at that time, what became C++11 was still known as C++0x), there was no compiler that could come anywhere near compiling it. Testing the code required replacing standard C++11 library components with similar components available in TR1 or from Boost or Just Software Solutions, and language features like auto, range-based for loops, lambda expressions, and template aliases had to be replaced with typically clumsier C++98/03 constructs that were more or less equivalent in meaning.

This week I tested my simple C++11 sample program with Stephan T. Lavavej's excellent  distribution of gcc 4.7 for Windows as well as Microsoft's VC11 beta.  gcc 4.7 has lots of support for C++11, but the concurrency API still seems to be largely missing, at least for Windows, so my sample program doesn't get very far with that compiler.  [Update 6 April 2012: As noted in the comments below, when invoked in the proper manner on the proper platform, gcc 4.7 compiles and runs my program without modification!]

 The situation with the VC11 beta is a lot better.  Only two lines have to be changed.  The template alias
  using WordCountMapType = std::unordered_map<std::string, std::size_t>;
needs to be replaced by its typedef equivalent:
  typedef std::unordered_map<std::string, std::size_t> WordCountMapType;
And the z length specifier in this call to printf,
  std::printf("  %-10s%10zu\n", (*it)->first.c_str(), (*it)->second);
needs to be replaced with its VC++ equivalent, I:
  std::printf("  %-10s%10Iu\n", (*it)->first.c_str(), (*it)->second);
Other than that, the demonstration program I wrote three years ago (which, in fairness to compiler writers, was two and a half years before the C++11 standard was ratified) compiles cleanly with VC11.

If you have access to a compiler that compiles my program without modification, please let me know! The program itself is below.  You can see a more colorful version of it, along with some commentary, and an example invocation and the corresponding output, on slides 13-15 of the free sample of my C++11 training materials.

Scott

#include <cstdio>
#include <iostream>
#include <iterator>
#include <string>
#include <fstream>
#include <algorithm>
#include <vector>
#include <unordered_map>  
#include <future>

using WordCountMapType = std::unordered_map<std::string, std::size_t>;

WordCountMapType wordsInFile(const char * const fileName)   // for each word
{                                                           // in file, return
  std::ifstream file(fileName);                             // # of
  WordCountMapType wordCounts;                              // occurrences

  for (std::string word; file >> word; ) {  
    ++wordCounts[word];
  }
  return wordCounts;
}

template<typename MapIt>                                            // print n most  
void showCommonWords(MapIt begin, MapIt end, const std::size_t n)   // common words
{                                                                   // in [begin, end)
  // typedef std::vector<MapIt> TempContainerType;
  // typedef typename TempContainerType::iterator IterType;
  std::vector<MapIt> wordIters;
  wordIters.reserve(std::distance(begin, end));
  for (auto i = begin; i != end; ++i) wordIters.push_back(i);

  auto sortedRangeEnd = wordIters.begin() + n;

  std::partial_sort(wordIters.begin(), sortedRangeEnd, wordIters.end(),
                    [](MapIt it1, MapIt it2){ return it1->second > it2->second; });

  for (auto it = wordIters.cbegin(); 
       it != sortedRangeEnd; 
       ++it) {
    std::printf("  %-10s%10zu\n", (*it)->first.c_str(), (*it)->second);
  }
}

int main(int argc, const char** argv)   // take list of file names on command line,
{                                       // print 20 most common words within;
                                        // process files concurrently
  std::vector<std::future<WordCountMapType>> futures;

  for (int argNum = 1; argNum < argc; ++argNum) {
    futures.push_back(std::async([=]{ return wordsInFile(argv[argNum]); }));
  }

  WordCountMapType wordCounts;
  for (auto& f : futures) {
    const auto wordCountInfoForFile = f.get();  // move map returned by wordsInFile

    for (const auto& wordInfo : wordCountInfoForFile) {
      wordCounts[wordInfo.first] += wordInfo.second;
    }
  }

  std::cout << wordCounts.size() << " words found.  Most common:\n" ;
 
  const std::size_t maxWordsToShow = 20;
  showCommonWords(wordCounts.begin(), wordCounts.end(), 
                  std::min(wordCounts.size(), maxWordsToShow));
}

Monday, March 12, 2012

My Training Courses through Other Vendors

For many years, I've allowed select outside technical trainers and training firms to use my course  materials with their clients. In cases where people approached me for training, but, due to scheduling or location or budgetary issues, etc., we were unable to work out an agreement, I'd refer them to one or more of these outside vendors.

These days, I face a challenge most people would love to have: there's more demand for my services than I can provide. Fortunately, thanks to these outside trainers and training firms, I have a viable suggestion for would-be training clients in cases where I can't do the work myself. In the past, my referrals to outside vendors have been ad hoc, but the issue arises often enough that I decided to put together a page at my web site listing the various individuals and companies who are authorized to use my training materials.

As a general rule, these vendors tend to have better scheduling flexibility than I do. I typically know the people who do the training, and I have great confidence in them. They use the exact same training materials that I use. As the person who did the research into the topics addressed by the materials and who created the materials themselves, I like to think I offer something nobody else can, but in cases where my doing a training gig is not possible, I'm pleased to be able to offer clients and would-be clients reasonable alternatives.

To view a summary of my authorized outside training vendors, please visit my Approved Outside Vendors page.

Thanks,

Scott