1

This (example) code crashes and I have no idea why. Compiler: gcc 4.8.3

#include <cstdio>

struct virtual_initialisation {
    virtual int foo() { return 4711; }

    template <typename T>
    virtual_initialisation(int (T::*foo)()) {
        // This is the crashing statement:
        fprintf(stderr, "%i\n", (dynamic_cast<T*>(this)->*foo)());
    }
};

struct A : virtual virtual_initialisation{
    int foo() { return 23; }

    A()
    : virtual_initialisation(&A::foo)
    {}
};

struct B : A {
    int foo() { return 42; }

    B()
    : virtual_initialisation(&B::foo)
    {}
};

int main(int argc, char * argv[]) {
    B b;
    return 0;
}

compiled using -O3, however -O0 yields the same result (except for more stack trace entries ;)

$ g++ -O3 -g stackoverflow.cpp -o stackoverflow && valgrind ./stackoverflow
==19328== Invalid read of size 8
==19328==    at 0x400745: main (oops.cpp:11)
==19328==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
Bodo Thiesen
  • 2,476
  • 18
  • 32
  • see this question http://stackoverflow.com/questions/6299266/dynamic-cast-of-this-inside-constructor , especially the accepted answer – PeterT Nov 26 '14 at 22:42
  • 1
    BTW: You would have been allowed to pass `&virtual_initialization::foo`, but not `&B::foo`. – Deduplicator Nov 26 '14 at 22:45
  • 1
    Exactly as deduplicator suggested ! The construction of an object is done starting with base class and ending with most derived class. Your dynamic cast to a derived class is done during construction of the base class, at a moment where the derived part was not yet constructed. vtable for B is perhap's not set at this stage, and that's why the standard makes such things UB – Christophe Nov 26 '14 at 23:14
  • 1
    @Christophe: Actually at that point the dynamic type is presently `B`, causing the dynamic cast to fail and return `NULL`. The OP is then dereferencing a null pointer. – Lightness Races in Orbit Nov 26 '14 at 23:53

0 Answers0