Binding Brain-farts at CppCon

First off, a quick reminder: I’m speaking at CppCon tomorrow afternoon1. So if you’re at the conference and are interested in transactional memory then stop by room 403 at 3:15 tomorrow.

[Update: one more brain-fart to get out of the way. Originally, in the following paragraph I substituted owner<T> for not_null<T>. I’m not quite that dumb, my question makes a bit more sense when applied to not_null<T> since a reference is sort of a pointer that can’t be null (there’s still the rebinding to consider, and thus it isn’t completely a pointer that can’t be null). Anyways, I’ve corrected the problem.]

[Another Update: I’ve added a footnote after having a discussion about bind and debuggers this morning.]

Next, let’s get the brain-fart out of the way. If you were at Bjarne Stroustrup’s keynote on Monday morning someone asked about why we need not_null<T> and couldn’t we just use references instead. Unintentionally this person was asking why we needed pointers, couldn’t we just use references instead? That was me. The answer is that pointers are rebindable where references aren’t (something I somehow forgot that morning). The same thing applies to not_null<T>. Not exactly the best start to the conference. In my (admittedly weak) defense, I didn’t sleep very well the night before and probably wasn’t firing on all cylinders. Putting aside my brain-fart, you should really check out his keynote and Herb Sutter’s companion keynote. They’re proposing some revolutionary stuff for C++.

Today I hit STL’s talk. His talks are always worth going to, and today’s was no exception (I should be using std::invoke in a lot of places that I’m not, I need to put a lot of &&’s on arguments to templated functions that are function objects to name a few useful things that I learned). Much of his advice was on what not to use from the <functional> header, here I’m going to concentrate on bind. He had lots of good reasons not to use it and they more than make the case for not using it. I just have one to add: stepping into a call to bind in the debugger is insanity inducing2. It’s the proverbial seeing how the sausage gets made and then it takes a lovecraftian turn and you’ve seen things that no human should ever see. I don’t want to dump on bind too much, it was a miracle back before we had lambdas. But miracle code that is elegant on the surface is often not pretty when you get into the details.

But why would you ever want to step into bind? Couldn’t you just put a break-point in the function that was bound and jump over all the unpleasantness? Much of the time that is possible, but lets say you have a bunch of calls to

template <typename Container_t, typename Func_t>
void do_something_to_some_stuff (Container_t& c, Func_t&& f)
   for (auto& i: c)
      f (i);

and one of them is causing problems. You’ll need to put a break-point on the call to f and step into it. If f is a lambda then you’ll jump directly to your lambda code since all you’re doing is calling the operator() on the function object that compiler has desugared the lambda into. If f is a bind then you won’t be so lucky. The call will still be to operator(), but this time that method is on the bind function object and a lot of really hairy stuff needs to done to call the bound function with the bound arguments and fill in any placeholders. You will step through a lot of code before you get to your own code that you’re interested in. So save yourself the trouble and use lambda instead.

  1. If anyone’s here at CppCon and wants to meet up just drop me a line through the side-bar over there.
  2. I should preface all this by telling you that the vast majority of my experience with bind comes from using boost::bind, not std::bind. I’m adding this now after having a chat with STL this morning about stepping into calls to bind objects in the debugger. Apparently doing this in newer implementations is not as bad as it was with the older implementations. It sounds like you still have to traverse a few circles of hell to get to the code that you care about, but there’s less circles to get through. So things may not be as bad as I’ve made them out to be here, but they’re still not as nice as just using a lambda.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: