1

I have specific class hierarchy which crashes at runtime.(Visual Studio 2017)

struct A{};
struct B
{
    auto f()
    {
        dynamic_cast<A *>(this);//triggers: Access violation
    }

    virtual ~B() = default;
};

struct C :virtual B, A//remove "virtual" to fix
{
    C()
    {
        f();
    }
    int a;//remove to fix
};
struct D :virtual C{};//remove "virtual" to fix

int main() 
{
    D d;
}

Question is: Is this problem of code or rather compiler bug?

I tried a lots of variations, but none of them was satisfying, since this code looks correct for me.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Agent Kat
  • 11
  • 2
  • `dynamic_cast` doesn't always work as expected when called form a constructor, much like `virtual` functions don't always do what you expect. – François Andrieux Nov 16 '18 at 21:17
  • @FrançoisAndrieux It depends what *you* expect! In a constructor of a non virtual base subobject with no virtual base, virtual functions and `dynamic_cast` and everything behave exactly like in a complete class of that type being constructed, even with abstract class that just completed with invalid definition of the pure virtual function. In practice in all implementations, everything matches the behavior of the complete class: layout, the value of all vptr so the formalization of expectations is easy. This isn't true if you have virtual bases as the base object isn't like a complete object. – curiousguy Nov 18 '18 at 03:43
  • @FrançoisAndrieux In which specific cases will `dynamic_cast` be ill behaved when used on a base class subject under construction where virtual inheritance is involved? (Of couse `dynamic_cast(this)` won't be used with a premature `this`.) – curiousguy Nov 18 '18 at 03:49
  • Please post the offsets of subobjects in `C` vs `D` – curiousguy Nov 18 '18 at 06:09
  • "`int a;//remove to fix`" I guess `C::a` makes `D` grow as it prevents `C` from being primary in complete `D` which changes... something. Please post the overhead of `D` with and without `C::a`. – curiousguy Nov 18 '18 at 06:50
  • @FrançoisAndrieux The only virtual functions you can never call from a constructor are direct destructor call (`this->~T();`) and deleting destructor (`delete this;`) – curiousguy Nov 18 '18 at 07:27
  • @Acorn "_This question already has an answer here_" Really? Where? – curiousguy Nov 20 '18 at 04:56
  • It seems that I must recognize polymorphism as inaccessible in constructors. It's a pity there are no warnings and it's easy to ignore that. – Agent Kat Nov 28 '18 at 16:18
  • @Pjoter Polymorphism works fine in constructors! – curiousguy Dec 02 '18 at 08:28

0 Answers0