I was given this piece of code to analyze and point out what’s wrong with it:

I was also able to compile and execute this program on my Mac; output from Xcode gives away the answer:

libc++abi.dylib: Pure virtual function called!
Program ended with exit code: 9

Program output.

But why? The constructor of Base calls void bar(), which in turn calls pure virtual void foo() = 0. The Derived overrides foo() so what’s the problem here?
Inside the constructor of Base, the type of this pointer is… Base. So the call to foo() inside bar() resolved to Base version of foo(), which is a pure virtual function lacking implementation. This is illegal and the compiler puts a check inside Base::foo() virtual function table pointing to __cxa_pure_virtual. That in turn calls __pthread_kill terminating the program.

__cxa_pure_virtual disassembly:


UPDATE:

Item #9 From Effective C++.

Related discussion: C++ corner case: You can implement pure virtual functions in the base class.

5 Replies to “Interview question, part 3”

  1. The “why” in this question is that C++ is more type safe than languages like Java and C# with respect to object construction. There is no possibility, as in those languages, of accessing not yet initialized stuff down in the most (or more) derived class.

    More that’s wrong with the code: in class

    Derived

    the keywords

    public

    and

    virtual

    are superfluous and should be omitted. Also the

    final

    keyword should probably be omitted, it’s wrong as a default. The arguments to

    main

    are declared but not used, and may cause undesired warning diagnostics.

    main

    returns

    1

    , which in practice is OK but indicates failure, and is not a standard-supported value. I think these issues are more serious, since they’re usually not diagnosed by the compiler or runtime support.

    After all, source code is mostly about communicating to humans, and all that redundant stuff just distracts.

    1. I disagree regarding the keywords. They more explicitly state the intent of the programmer. I know from the compiler stand point they’re not needed, but I like to put them in my code to quickly see, for example, that the derived class overrides a virtual function, inherits publicly from Base, etc, etc. But I guess we’re really discussing style at this point 🙂

        1. I think it helps the newcomers to C++ see the stated intent more clearly. I agree that non of those keywords are needed, but how many new C++ developers know for example that the only difference between

          struct

          and

          class

          is the default visibility? I personally prefer ALL keywords that can be in place to be in place. But again, we’re really discussing style, not validity of code.

          1. Nobody has mentioned that Base does not have a virtual destructor.

Leave a Reply