Bug of the week

Today we are going to see a case study illustrating a bug. Not a very spectacular one: a typical bug one would encounter in everyday work. We will start with the symptoms, identify the root cause, and suggest measures to prevent similar things from happening in the future. Continue reading

Posted in programming | Tagged , , | 1 Comment

A conditional copy constructor

In this post we will try to define a ‘wrapper’ class template that does or does not have a copy constructor depending on whether the wrapped class has it. This will be a good opportunity to explore in depth a couple of advanced C++ features. Note that this is a rather advanced topic and, unless you are writing or maintaining a generic library, you will probably never need this knowledge.

The problem

By a wrapper class I mean something like boost::optional<T>. It wraps a value of type T: it is an ‘almost type T’ with some special features. Additionally, as in the case of optional, our wrapper does not inherit from T, nor does it contain a data member of type T.

Our goal is that for any type T the following holds:

std::is_copy_constructible<T>::value ==
std::is_copy_constructible<Wrapper<T>>::value;

Continue reading

Posted in programming | Tagged , , , , , | 3 Comments

Desired compile-time failures

When new features are proposed to C++ it is desired that they do not introduce breaking changes. This is typically understood as:

  1. Every program that used to compile (was well formed), continues to compile with the same semantics.
  2. A program that failed to compile (was ill-formed), can now be made well formed and assigned new desired semantics.

For instance, the following was an invalid C++03 program:

void feature(std::string s1)
{
  std::string s2 = std::move(s1); // no std::move in C++03
}

Therefore, it is no harm when we make it well formed code in C++11 and assign it some useful semantics. This rule is not followed in 100% of the cases, but this is the idea in general.

However, even though it works in most of the cases, I believe that this criterion of a “safe addition” is not technically correct, as it fails to take into account an important fact: failure to compile certain programs is a useful, important feature, and if these programs suddenly start to compile, it can cause harm. In this post we will go through the cases where compile-time failure is considered a useful feature. Continue reading

Posted in programming | Tagged , | 12 Comments

Defensive programming

Have you ever asked yourself, or participated in a discussion on whether “defensive programming”is a good or a bad thing? The issue is controversial, and recently, while watching talk “Defensive Programming Done Right, Part I” by John Lakos, I realized (I think) why. Term “undefined behavior” means different things to different people. Continue reading

Posted in programming | Tagged | 25 Comments

Using assertions

This post is a response to my recent encounters with fellow programmers who appear to me to be missing the point of assertions and fail to appreciate their usefulness. The first post I have ever written here was on assertions, I still find it good, so there is no need to repeat it; here I will only describe how I observe people treat assertions and why I believe it is wrong. Continue reading

Posted in programming | Tagged , | 10 Comments

A gotcha with ptr_vector

Recently I came across an interesting gotcha with Boost.Pointer Container library in my project. Making some incorrect assumptions as to what the library does could cause a bug.

What would you use boost::ptr_vector for? Why would you need to have a vector of pointers, which you want to delete yourself? Is it because:

  1. You want the objects to remain at the same address even if you re-allocate the array under the vector?
  2. You want to inter-operate with a library that already deals with owing pointers?
  3. You want it to be faster than if you were storing values in std::vector?
  4. You want the “polymorphic behavior” of your objects?

If your reason is (1) or (2) and you are not concerned with performance too much, you would probably do the right thing.

If your reason is (3), it is likely that you would be picking the slower solution. But do not trust me on that: measure the two solutions and check if ptr_vector is really faster.

If your reason is (4) and your familiarity with ptr_vector is superficial (as was mine when writing this post), it is likely that you would be implementing a bug. In this post we will be exploring this use case. Continue reading

Posted in programming | Tagged , , | 23 Comments

A gotcha with Optional

This post is about one gotcha in Boost.Optional library. When starting to use it, you might get the impression that when you try to put optional<T> where T is expected, you will get a compile-time error. In most of the cases it is exactly so, but sometimes you may get really surprised. Continue reading

Posted in programming | Tagged , , , | 16 Comments