Posted by: rmn on: 27/09/2009
Okay, so here’s how this category is going to work. I will post and explain a few lines of code, with one (or more) defect(s) hidden in them. The defect will not be trivial (at least not intentionally). Your job is to spot and explain the bug(s) – once there’s at least one comment about what i was aiming for, I will update the post with an explanation.
Find below the first post, on the topic of file signatures (aka magic numbers).
class MagicMixin { // Mixin for checking the magic number
protected:
virtual bool chkMagic (const std::string &filename) const {
// full implementation removed for simplicity..
std::string magic = getMagic();
return beginning(filename, magic.size()) == magic;
}
virtual std::string getMagic () const = 0;
};
class MP3File : protected MagicMixin { // MP3 files
public:
MP3File (const std::string &filename) {
if (!chkMagic(filename))
throw std::string(filename + " isn't an mp3.");
}
// more functionality..
protected:
virtual std::string getMagic () const { return "ID3"; }
};
int main () { // usage example
MP3File m("song.mp3");
return 0;
}
And a small, yet thorough, explanation:
The error was in the indirect invocation of a virtual function during the construction of MP3File, which caused a pure virtual function call in this case. Further explanation can be found in this post.
30/09/2009 at 01:11
The vtable is not ready until construction is done. Therefore, the call to the virtual function getMagic from MagicMixin::chkMagic results in invocation of the pure virtual method MagicMixin::getMagic, which has no body. That sounds quite bad.
Nice post.