Monday, January 23, 2006

deemed to fail

On Mondays people often write broken code. Actually they do it the other days as well but this leads to the following C++ puzzle for today.

The following code is broken and any instantiation of an object of a class derived from this abstract class is deemed to fail. Explain why this is the case. Note that your first thought might be wrong!

struct broken {
    virtual void v() = 0;
    void n() { v(); }
    broken() { n(); }
};

4 comments:

Loki said...

n() should be virtual.
Because n() is not marked as virtual, it breaks the virtual calling chain.
When subclassing, the subclass constructor will implicetely call broken().
broken() will call n(), but because n() is not virtual (in broken's scope), n() itself will try to call v() from broken instead of the subclasses' implementation of v()

Robert said...

Sorry loki, your first thought was wrong as predicted. ;-)

n() is not the function that does the illegal thing because it just calls the function from the object's virtual function table. Actually it is calling v() from the base class in the case that fails but your explanation why it does so was not correct.

Unknown said...

My guess is that the problem is that, at the time broken() calls v(), the object hasn't been fully constructed yet. The vtable will probably be there, but of course all instance variables of the subclass will still be un-initialized.

Thus, it's easy to screw up here, though it's at least *possible* to write working code (though I guess a better programmer would not make v() virtual to avoid this).

Robert said...

Your first observation that the object is not yet fully constructed is correct but the instance variables of the subclass are not the issue because nobody is using them.