Category Archives: Software Development

The safe bool idiom in C++

I’m in the process of writing a series of articles on C++11, and a passing explanation of this idiom grew to become a whole article. There’s no original content here, but I learned something in writing it and I hope it might be useful to someone out there.

It’s idiomatic C++ to evaluate a variable in boolean context, even when it’s not a boolean variable, to detect whether that variable is “not a thing”. For example, with a pointer variable it checks whether the pointer is null or not:

if (my_pointer) {
   // my_pointer is not null
}

Exactly what this boolean conversion means varies by type, but experience shows that one’s intuitive sense of how this should work is pretty consistent and this can make code more expressive. Some would say this is bad practice, but for now I’ll assume that it’s desirable.

If you’re writing a user-defined class, you want to follow this kind of pattern if possible. If 0 is false, then surely the (0, 0, 0) point in a 3D space is false? Of course, C++ lets you make your user-defined type act pretty much however you want it to, so of course you can define an implicit conversion to bool:

struct TestResult {
   //...
 
   operator bool() const {
      return m_passed;
   }
};

The problem with this is that it’s not just a conversion to bool. It’s a conversion to a type that is part of a system of numeric types, and the types allow conversions between them that allow you do do silly things. For example, you can assign it to an integer:

TestResult test_result;
int i = test_result; // Should really be a compile error

More insidiously, things like the left-shift operator suddenly work on your objects in ways that you might not expect:

test_result << i;

As is the way with all C++ design issues, you can get around this by careful application of edge cases of language tools that were meant for something else. You can expose a conversion to any type you like. Void pointers are a reasonable thing to try, because there’s not a lot you can do with a void pointer:

struct TestResult {
   operator void *() {
      return m_passed ? this : 0;
   }
};

There’s no implicit conversion of void pointers in C++, so this seems reasonably safe. However, one thing you can do with a void pointer is call delete, and there’s no way to prevent that from compiling:

TestResult tr;
delete tr; // Gets converted to pointer, attempts to delete a stack variable!

You could try returning a pointer other than this, which could eat least mean that the code would crash horribly the moment delete was called:

struct TestResult {
   operator void *() {
      return m_passed ? (void *)1 : (void *)0;
   }
};

But this is horrible. Besides, there’s no guarantee that you won’t segfault just by referencing pointers to non-allocated portions of memory (i.e. segfault even in the good case where you’re just converting the result straight to boolean).

A common trick in C++ (which dates from an earlier related trick in C) is to give code an incomplete type to work with. If you have a class declaration in scope, but no definition, then you can handle pointers to the incomplete class but there are limits to what you can do. In particular, you can’t dereference or delete the pointer. So you can safely pass such a pointer back to the caller and allow them to compare it with NULL without worrying that they can delete it.

How can you get a pointer to a type that you can be sure won’t be defined? You define one for yourself. A nested class will do nicely:

struct TestResult {
  //...
 
  class never_defined;
 
  operator const never_defined*() {
    return m_passed ? reinterpret_cast<const never_defined *>(this) : 0;
  }
};

Unfortunately, while pointers to incomplete types can’t be dereferenced, you can still compare them:

TestResult x, y;
 
// later ..
 
if (x > y) // Really shouldn't compile
{
 // ...
}

Can we prevent this? Just one more dip into the junk draw of C++ will sort us out. One of the more overlooked features of C++: the pointer-to-member (in this case, a pointer to member function).

A pointer to member isn’t like a regular pointer. A regular pointer points to data of a particular type in the memory space. A pointer to member operates in the world of classes, not objects. The pointer to member identifies a member of a particular type on a particular class; if you have a int Foo::*, it can point to any integer member of the Foo class. When you set the value of your pointer-to-member, it points to that same member on every instance of Foo (or, equivalently, on no particular Foo instance at all).

Pointers to member can’t be compared to each other, so we can combine our conversion-to-pointer trick with a pointer-to-member and have (at last) a safe boolean conversion:

struct TestResult {
  //...
 
  typedef void (TestResult::*bool_type)() const;
  void do_nothing() const;
 
  operator bool_type() const {
    return m_passed ? &TestResult::do_nothing : 0;
  }
};

If you’re not used to unpacking these definitions, the line:

typedef void (TestResult::*bool_type)() const;

deserves some explanation. This is just like any other typedef, except that since it’s a function typedef the name of the type defined (bool_type) goes in the middle and not on the right hand side. The TestResult::* bit identifies that we’re defining a type that points to a member of TestResult, rather than a regular pointer. The remaining stuff just tells us that we’re talking about a const function that takes no arguments and returns void.

For an example of this being done in the wild, you can see the safe_bool class within Boost::Spirit.

Learning programming with stories

Over a year ago I came across Python Pals, a project to write stories that motivate young people to learn programming. I always intended to write about the project but forgot to do so.

The concept for the stories is inspired by the Bytes Brothers stories of old, and follows a similar format: in each story, the pair of young protagonists come across a problem (such as calculating the exact age difference between their parents) that gives rise to a simple solution that they work together to implement. The story contains code snippets that the reader can use to follow along for themselves.

I love the concept, and the stories are certainly a refreshing change from the status quo in teaching programming. Using female protagonists is a nice modernisation, though I found the trendy inclusion of a Raspberry Pi irritating: you don’t need a Raspberry Pi to learn to write command-line programs in Python. In fact, the Pi can only make the task harder and implies that special equipment is needed (laptops that are capable of running Python are still massively more ubiquitous than Raspberry Pi’s, despite the latter’s low price and status as a media darling).

My instinct is to worry that this story-based approach is solving the wrong problem: my own experience was that it was very easy to get started with simple command-line programs and much harder to get as far as making things that felt like “real” programs. The idea that computers could be made to do things came easily to me, but I felt that writing a tool or game that someone else would want to use was well out of my reach. I’d have been better cutting my teeth on something that made the installer and GUI easy, such as the Android platform (or even not-quite-programming environments like writing AVS presets).

But I don’t have a lot of experience teaching young people to program, and my experience was a long time ago and may be atypical, so I’m happy to be proven wrong here. I don’t think we need to be teaching all children to program, but we should be providing resources for all those who are interested. A diverse range of solutions has to be a good approach.

Why you can’t write a good FizzBuzz implementation

At work the other day, conversation on a mailing list fell to the fact that most programmers can’t write FizzBuzz. For those of you who haven’t heard this discussed before, the point is that you set the most trivial possible programming task for interview candidates: Write an algorithm that prints numbers from 1 to 100, except that it should print “fizz” instead of multiples of 3, “buzz” instead of multiples of 5, and “fizzbuzz” for numbers that are both. A full implementation in the most straightforward way involves just two control structures: A for loop wrapping round an if condition.

Naturally, since we are all programmers and somewhat competitive, we had a go at solving the problem ourselves in the most “creative” way possible. I had a number theoretic solution (repeatedly sum the digits of the number until you have a single-digit number, then compare against 3, 6 and 9 to determine whether it is a multiple of 3) and a slightly more elegant solution involving itertools in Python: one iterator produced the “fizz”s, another iterator the “buzz”s, and an imap knitted them together into a single sequence.

My second solution was controversial: some thought it was elegant and idiomatic Python. Some thought that it was pretentious obfuscation. I’m going to argue that it’s impossible to tell which of these is true.

Good code is about the relationship between the problem domain and the representation in code. The problem domain is comprised of the stuff that is known by the person with a problem to solve. We can assume they’re intelligent, but they don’t (and shouldn’t need to) know anything about how the program is implemented. The best code preserves and makes accessible the relevant aspects of the problem domain, and minimises the interference of “accidental” details of programming that have no representation in the problem domain.

I maintain that the FizzBuzz problem domain is so badly under-specified that it’s impossible to know how a really good solution would look. There are lots of problems that are isomorphic to FizzBuzz but have different characteristics, that would (if the problem were not so trivial) ideally be approached in different ways. Perhaps “fizz” and “buzz” are two entirely different concepts that different parts of the business want to talk about, in which case my dual-iterator solution might help to make this plain. Or perhaps it’s going to be extended into some kind of number theoretic analysis, in which case we should write our code so that the mathematical properties are foremost (perhaps we introduce a prime factorisation concept from the start). Or maybe we’re writing single-use code for the accounting department to produce a report during the merger of two companies.

I hope it goes without saying that simplicity is also an important feature, and that in the case of something as trivial as FizzBuzz simplicity ought always to win out over other concerns. But sometimes when programmers talk across boundaries of industry and experience it’s necessary to treat toy problems as if they were a bit more than that, and I felt like there was some mileage in that this time.