Vladimir Prus


Monday, March 21, 2005

Why constructors crash

Of course, C++ constructors can crash for absolutely any reason. The interesting reason is member initialization. Consider this code:

C::C(const std::string& a) : a(a) {}
which is perfectly OK. The C++ standard allows to use parameter 'a' when initializing member 'a'. But consider the following example:
C::C(const std::string& acuracy) : accuracy(accuracy) {}
A small typo causes initialization of the member with itself, which can likely crash. This is one reason why adding "m_" prefix to member names is a good idea.

Just now, I've seen a more complicated example. A colleague first shown a code like in the first example and asked if it's OK. I immediately replied that it's OK unless there's a typo. But the real crash was a bit more contrived:

class Entry {
     Entry(const std::string& EntryId) : EntryId(EntryId) {}
     std::string EntryId;
class LogEntry : public Entry
    LogEntry(const std::string& Id): Entry(EntryId) {}    
Here, if the parameter of the second constructor was named "EntryId", everything would work. As it stands, the base constructor is passed the base member as initializer and again the member is initialized with itself.

Moral of the story

  1. Use the "m_" prefix
  2. Make all data members private

No comments: