Why Initializer Lists don’t Work with Base Members


As you might know, you cannot initialize a base member in a derived constructors initializer list:

struct Base {
    int base_mem;
};

struct Derived : public Base {
    Derived(int i) : base_mem(i) {} //Error!
};

int main() {
    Derived(42);
}

This is not allowed. But why? There are two key points to get here:

1: What is the point of an initializer list in the first place?
If you don’t use an initializer list, but initialize all your objects in the constructor body, they will first be created once, even before the constructor body, and then you will re-assign them. This might be a performance-problem, but could also be a bigger problem if the constructors of those types have side-effects like hitting a database, acquiring some resource etc.

2: When are the different parts of an object constructed?
When constructing a Derived object, the first thing that happens is that Bases default constructor is invoked. In this example, I didn’t declare one, so the compiler will generate one for me. When this constructor is done, including both its initializer-list and its body, it is Derived()s turn.

This means that when C++ gets around to Derived()s initializer, the Base part of the object has already been created, all Base members are initialized, and we have lost the advantage of using initializer lists.

So how do we solve this? Make sure the Derived constructor explicitly specifies which Base constructor to use, and have this one initialize the variable. Example:

struct Base {
    Base(int i) : base_mem(i) {}
    int base_mem;
};

struct Derived : public Base {
    Derived(int i) : Base(i) {}
};

Array Initialization Initializes all Elements


I was talking about C++ with a Java programmer the other day, as he had to work on a bit of C++ code. I discovered that it isn’t necessarily obvious that all the elements in an array are constructed when the array is initialized. That is however always the case.

For arrays of built-in types, the values aren’t actually set to a specific default (except for non-local and static arrays), and will end up having arbitrary values.

For arrays of a user-defined type, the default constructor is used for all the array elements. If you don’t want this behaviour, you need to use an array of pointers. All the elements will still be initialized, but the elements being initialized are now the pointers, not the actual objects. It is worth mentioning that pointers count as a built in type, and elements of non-local and static arrays will have undefined values. In particular, they are not initialized to point to NULL.

The reason why all the elements are initialized is that there is no such thing as a “null-object”. You can have a null-pointer not pointing to anything, but you cannot have an actual object that isn’t really an object, so to speak. This of course goes for Java as well, but here, an array of a user-defined type is actually an array of pointers, even though you don’t see any *s in the code. (Java uses pointer semantics for user-defined types and value semantics for built-in types.)

Here is a summary using actual C++ code:

int ints[10]; //Non-local array, all elements ==0
int func() {
    int ints[10]; //Local array, no default value is set, but all elements are fully usable ints.
    static int sints[10]; //Static local array, all elements are initialized to 0
    Foo foos[10]; //User-defined type, all elements are constructed using the default constructor Foo::Foo();
    Foo *foos[10]; //Local array, no default value is set. The pointers point all over the place.
}

If your class has no public default constructor, it is impossible to create an array of such objects:

class NoDefault {
private:
    NoDefault(); //Make default constructor private, and hence unusable
};
NoDefault nodefaults[10]; //Impossible!
NoDefault *pnodefaults[10]; //This is fine, no objects are constructed, only pointers.

Note also that you cannot have an array of references. The most obvious reason is that a reference must always refer to an object. There is no such thing as a “null-reference”. One could however imagine getting around this using an initializer list, like this:

    Foo f1, f2;
    Foo& foors[2] = {f1, f2};

Now we don’t try to initialize references that don’t refer to anything. This is still not allowed though. One reason is that you cannot point to a reference, so accessing elements in the array in a normal sense like foors[1] wouldn’t make sense. In C++, you can only have arrays of objects, and references are not objects. (Pointers are objects though.)

In summary:

  • Elements of arrays of a user-defined type are initialized using the default constructor.
  • Elements of local non-static arrays of a built-in type are not explicitly initialized, and will have arbitrary values.
  • Elements of non-local and static arrays of a built-in type are initialized to their default value (0).
  • You cannot have an array of a user-defined type without a public default constructor.
  • You can only have arrays of objects and pointers, not references.

Be Careful with Static Variables


In a project I am working on, we are using Google Test to write and run our unit tests. Google Test is a really nice unit test framework, but that is another story. The thing you need to know for this post, is that it has a flag --gtest_repeat, which will make it run the test several times.

The other day, we ran into a strange problem. The following would work:
$ ./Test; ./Test
whereas the following would break:
$ ./Test --gtest_repeat=2

The code that was being exercised involves quite a bit of socket programming, so at first we wasted some time looking for improper shutdowns and reuse of sockets, but that was a dead end. We also confirmed that our SetUp() and TearDown() was executed properly for each time the test ran. Then we discovered that running the test manually two times in a row worked, and ended up a bit puzzled.

If you read the title, you might have figured out our problem already, but here it is:

Non-local static variables are always initialized before main() is executed. We used a static variable to keep track of the state in a dummy object for our test, and relied on the runtime system to initialize it for us. When we ran the test twice manually, the binary was actually executed twice, which resulted in the variable also being initialized twice. But when passing --gtest_repeat to Google Tests main(), the binary was only executed once, resulting in the variable only being initialized once, again resulting in keeping state from one pass to the next. Initializing the variable manually in a SetUp() function fixed the problem.

Appendix A: Why non-local static variables are initialized before main()

Imagine you have a global static variable defined in one translation unit (a translation unit is basically one .cc-file with headers included), but declared and used in several others. There is no way for the compiler to know where it will be used first, without having access to all translation units, which only the linker has. The best C++ can do is to have the runtime system initialize all such variables before main() is executed. Also note that due to the same argument, there is no guaranteed order of initialization of non-local static variables.

But why can’t the variable just be automatically wrapped with code that initializes it the first time it is accessed? Think about it for a moment. Where would that code need to be placed? In all the places that accesses that variable! And again, this might be in many separate translation units.

When variables are initialized in C++ is an interesting topic in itself, and I guess I will be coming back to that in a later post.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.

Make APIs hard to use incorrectly


So far I have written a couple of posts about bad practices I have found in other peoples code. Todays blunder is however one I was about to commit myself. A library I was extending had this (as usual, simplified) function:

void Library::write(const char* c, int i);

This was however not always a safe thing to do, so I found all the callers had wrapped it with almost identical code to protect it. I decided to add a method to the library, doing exactly the same thing, but with the added safety-wrapping. Fortunately, I didn’t even need to change the signature, so I could easily make a new function

void Library::writeSafely(const char* c, int i) {
    safety();
    write(c,i);
    more_safety();
}

and change all the callers to use this new function. Luckily, we still had control of all the users of this API, so this was no big deal. Can you spot my mistake?

The title is kind of revealing, hinting at the API design best practice “Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly”, which for instance Scott Meyers mentions both in 97 Things Every Programmer Should Know (Chapter 55) and Effective C++ (Item 18).

If you need to provide both a safe and an unsafe version of a function, make the safe version the easiest to use. In this case, instead of just adding the new function, I renamed the old function write_raw(), and made a new, safe function write() that wrapped write_raw().

In a few months, someone unfamiliar with this API will come along looking to write something, and will most certainly use write() after skimming through the API. He will now be defaulting to the safe version, if he wants raw access he will need to dig a bit further.

And that someone might just as well be myself.

How ++c can be Faster than c++


In for-loops, people will tell you to always increment using ++c instead of c++. Why exactly is this? And will it affect your program in any way?

The observable difference between ++c and c++ is that the former evaluates to c+1, and the latter to c:

int main() {
    int c = 1;
    cout << ++c << endl;  // 2
    cout << c++ << endl;  // still 2
    cout << c << endl;  // 3
}

First of all, to get that question out of the way: This does not mean that the first alternative will increment c at the beginning of the iteration. Both alternatives increment c at the end of each iteration:

int main() {
    for (int c = 0; c < 1; c++) {
        cout << c << endl; // 0
    }
    for (int c = 0; c < 1; ++c) {
        cout << c << endl; // still 0
    }
}

So what then, is the point? Speed is.

Consider how the ++c operator would be implemented. No one will ever use the old value of c, so the implementer is free to increment c and then provide a reference to the freshly updated object. Now consider c++. Here, the implementer needs to provide a reference to the not-updated object, but still increment it. A common way to do this is to make an unmodified copy of c, increment the original c, and then return the copy. See the following example:

struct C {
    int _i;
    C(int i = 0) : _i(i){}

    C& operator++() {
        _i++;
        return *this;
    }

    C operator++(int) {
        C tmp(_i);
        _i++;
        return tmp;
    }
};

ostream& operator<< (ostream& os, const C& c) {
    os << c._i;
    return os;
}

int main () {
    C c;
    cout << c << endl; //0
    cout << c++ << endl; //0
    cout << ++c << endl; //2
}

As you can see, this introduces unnecessary overhead, especially for complex classes.

But what about built in types? For these, there will typically be no overhead using c++, but if you get into the habit of always using ++c, you won’t forget when you are incrementing more complex classes.

And as @tfheen points out, “[cases like the above example will be optimized away by] any compiler less than 30 years old.”, so this advice is probably not that relevant anymore. But now at least you know the reasoning when you see it.

A Quick and Simple Worklog


(This post does not concern C++. I continue to post about C++ every Friday, but I will sometimes post about other topics related to software development in between. Feel free to ignore these if you are here for C++ only.)

I have a tendency to forget what I did the previous day on the standups, especially the Monday ones. Also, at the end of the month, I need to send a summary of what I did to my manager, which is even harder. I considered looking for some web based logging software, or maybe setting up a wiki, but I ended up with this really simple solution:

$ cat ~/bin/log
#!/bin/bash
DATE=`date +%Y-%m-%d`
LOGFILE=~/Documents/log.txt
egrep "^$DATE$" $LOGFILE
if [ $? != 0 ]; then
    echo $DATE << $LOGFILE
fi
gvim -c ':$' $LOGFILE

Now I can just press Alt+F2 (in Gnome), type log, and the log opens in gvim, with the cursor on the last line. If it is the first time I open the log on a particular day, the current date is automatically appended to the end of the file.

A short explaination of the script:

  • 2: Get todays date on the format YYYY-MM-DD
  • 4-7: Check if the date has already been inserted into the log-file, if not, append it at the end
  • 8: Open gvim. The -c option lists commands that will be executed after the file is opened. :$ places the cursor on the last line in the file.

Finally a simple example of my log:

2010-04-01
Implemented foo
Fixed bug #1337
2010-04-02
Implemented bar
Went too fizzbuzz architecture meeting

Quick, simple, and no dependencies on external services.

Friends vs. Dependency Injections


I recently came across an interresting post on Chris’s Wiki. In short, Chris prefers not to use dependency injection for tests, but rather monkey-patch. The reason for doing this is that he “would rather have clean code and ugly tests than dirty code and cleaner tests”, which makes sense to me.

Spending most of my time in statically typed languages, monkey patching is a luxury (or should I say long rope) we don’t have, but it got me thinking whether we could do something similar in C++. Usually, people will tell you not to make your test-class (T) a friend of the class being exercised (E), since you will often end up testing for state instead of behaviour. But what if we make T a friend of E, and use that friendship only to sneakily substitute parts of E? For instance to swap out a real class it depends on (D) with a stub (DStub) providing synthetic data.

If E in production always uses the same type of D, it can instantiate D in its constructor, and we won’t have to inject an object of this type. In this case, using dependency injection would reduce readability just to support testing. If we let E set up its own D, the test can swap it out after E::E() has done its job, and the production code will have no traces of test-specific code. There are a few issues though:

If E stores the D object by pointer, we might need to manually delete the D it is pointing to before setting it to point to a DStub. (In production E would usually do this in its destructor.)

If E stores the D object by value, when we try to assign to it, it will use D’s copy assignment operator, not the one in DStub, and we will experience slicing. We of course also depend on D being copyable in the first place, but this requirement is not introduced by our test, it goes for the production code as well.

The last option, E storing the D object by reference, is only possible if we are already using dependency injection, or if something seriously weird is going on. You might want to think about why.)

Finally, and maybe most important of all, we require that all the methods in D that we want to stub are virtual.

So in conclusion, you probably shouldn’t monkey around, not even with good friends.

Appendix A, Answers to Exercises:

Why can’t we use references without dependency injection? Have a look at the following code:

struct D {};

struct E {
    D& d;
};

int main() {
    E e;
}

If you try to compile this, your compiler will complain about uninitialized reference members. A reference can never refer to “nothing” (unlike a pointer to null), and must be initialized with some object. This has to be done in the initializer list. When the body of the constructor is reached, it is already too late, as all members are initialized at this point.

How about this constructor for E then? E() : d(D()) {}; This won’t work, the object created will be a temporary, and references cannot refer to a temporary. This is one of the things that make them safer than pointers.

The only way to make this work would be to have a constructor that looks like this: E() : d(*(new D())) {};, and if it does, you have bigger issues than testability!

Always catch exceptions by reference


Some code I am responsible for at work recently got exposed to a new environment, and suddenly started logging exceptions. After some investigation, my colleague Thomas and I felt pretty sure what was going on, except the exception we saw in the logs was of a different type than the one that was thrown by the suspected culprit. What was going on, could the error be some place else after all? Then we looked at some intermediate code in the call hierarchy, and found the following (as usual, simplified) code :

class Exception{};
class SpecialException : public Exception {};

try {
    throw SpecialException();
} catch (Exception e) {
    cout << "Caught" << typeid(e).name() << endl;
}

Spot the problem? catch (Exception e) results in slicing. We are catching by value, which results in copying the exception. But since we are catching Exception, not SpecialException, Exception‘s copy construcor is called, and we lose the SpecialException part of the object. Here is an illustration of the Exception copy constructor in action:

Exception copy constructor slices away the SpecialException part of the object

On the left side is the full SpecialException object, with its Exception part shown in green. The green line illustrates the copy constructor, which only lets the Exception part of the object throuh.

The right way to write this would be catch (const Exception& e), which would result in a reference to the original SpecialException. Thanks to polymorphism, this program will now print “Caught SpecialException”, whereas the original example prints “Caught Exception”.

As a side note, always throw by value, not by pointer. That is, do throw Exception();, not throw new Exception();. After all, you want to be throwing an exception, not a pointer. And as always, there is no point in allocating on the heap if you don’t have to. Requiring people to clean up memory for you when catching is not very polite.

C++0x highlights #0: Range Based For Loop


Herb Sutter has some good news, C++0x looks like it could end up as C++11! This is going to be a great update to the C++ language. Lots of advanced features, like closures, a new memory model, portable threading support etc., are coming, but I think the one that I miss most often is the really simple Range Based For Loop (especially combined with Type Inference).

The following for loop:

map<SomeClass, vector> someclass_strings_map;
for (map<SomeClass, vector>::const_iterator it = someclass_strings_map.begin();
    it != someclass_strings_map.end(); ++it) {
    do_something_with(it->second);
}

is one of the reasons the Python, Ruby (and Java since 1.5) people laugh at us. But next year, we will be able to do:

for (auto x : foo_strings_map) {
        do_something_with(x.second);
}

PS: while I was compiling this example, I remembered another tiny improvement, you can now do map<Foo, vector<string>>. Notice the missing space? C++ no longer confuses nested templates with the shift/stream operator. Currently, you need an extra space: map<Foo, vector<string> >

PPS: If do_something_with() is a simple function this could be done with a for_each and a lambda/closure, but that is another story.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.

XP Meetup: 97 Things Every Programmer Should Know


I know this is cheating, I am supposed to blog on Fridays, but I am really excited about Monday’s XP Meetup. Kevlin Henney is going to present his new book 97 Things Every Programmer Should Know: Collective Wisdom from the Experts, together with some of the Scandinavian contributors.

I have seen Kevlin in a couple of courses at work, and also a couple of times at JavaZone. He is both knowledgeable, fun and engaging, so this should be a great night.

This is happening at Radisson Blu Scandinavia Hotel in Oslo, Monday 22 March at 6:30 PM, and there are still 14 more free seats! If you want to attend, join Oslo XP Meetup on meetup.com.