Wednesday, August 19, 2009

Episode Six: Boolsh*t

The built-in type bool is an integral type that can have one of the two values `true` or `false`. Despite being an integral type there are no signed, unsigned, short, or long bool types or values. There are some special situations where extra care is needed when working with bools:

  • Conversion to bool: A class with an unambiguous meaning of validity could benefit from a conversion to bool. Such conversion allows definition and subsequent testing for validity, something widely used in conditional statements. A conversion operator to bool seems to be the obvious approach, but it comes with harmful side effects due to the lack of an `explicit` specifier for conversions operators. Since bool is an integral type, it can be arithmetically operated, which means that an object convertible to bool will also be arithmetically operable! To overcome these and other side effects, a technique usually known as the 'safe bool idiom' was developed [1]. Such technique makes use of pointer to member objects, which are convertible to bool but differ from regular pointers in that there is no pointer-to-member arithmetic.
  • Overloading logical operators: When designing a class which behaves like a bool, overloading logical operators (&&, ||, etc) may be tempting. For instance, when writing a tri-state boolean (See Boost.Tribool [2]) its possible to introducing logical operator overloads to keep the logical semantics of the 3rd state. However, to keep one's semantics another one's have to go. Logical operators are short circuited; they do not perform element accesses beyond what is required to determine the result. Once a logical operator has been overloaded, there is no way it can continue to be short circuited. The syntactic sugar hardly ever justifies such surprise factor.
  • std::vector< bool >: A vector of bools is explicitly specialized to hold bits rather than bools. It can be seen as a dynamic counterpart to std::bitset, and it should have been defined as such. While it drastically reduces space allocation, `std::vector< bool >` does not provide the same features/guarantees than any other vector, and its not even a container according to the general container requirements! This means generic code using std::vector may not be valid for vectors of bools.
[1] http://www.artima.com/cppsource/safebool.html
[2] http://www.boost.org/doc/html/tribool.html

No comments:

Post a Comment