Is the result of valid dynamic cast always equal to the result ofcorrespondent static cast?

Discussion in 'C++' started by Pavel, Sep 17, 2010.

  1. Pavel

    Pavel Guest

    Let us assume that A and B are classes, the variable aPtr has type A*,
    and the code containing the following assert statement compiles without
    error:

    assert(!dynamic_cast<B*>(aPtr)
    || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));


    Can A and B be defined in a way that the assertion would fail?

    TIA,
    -Pavel
    Pavel, Sep 17, 2010
    #1
    1. Advertising

  2. Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    Pavel wrote:
    > Let us assume that A and B are classes, the variable aPtr has type A*,
    > and the code containing the following assert statement compiles without
    > error:
    >
    > assert(!dynamic_cast<B*>(aPtr)
    > || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));
    >
    >
    > Can A and B be defined in a way that the assertion would fail?



    AFAIK no, since the first condition checks whether a dynamic cast is
    allowed.


    Marcel
    Marcel Müller, Sep 17, 2010
    #2
    1. Advertising

  3. Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    Pavel wrote, On 17.9.2010 13:33:
    > Let us assume that A and B are classes, the variable aPtr has type A*, and
    > the code containing the following assert statement compiles without error:
    >
    > assert(!dynamic_cast<B*>(aPtr)
    > || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));
    >
    >
    > Can A and B be defined in a way that the assertion would fail?

    The following gives me false with codepad.org:

    #include <iostream>

    struct A
    {
    virtual ~A ()
    { }
    };

    struct C
    {
    virtual ~C ()
    { }
    };

    struct B : C, A
    { };

    struct E : A
    { };

    struct D : E, B
    { };

    int
    main ()
    {
    D d;
    A * aPtr = static_cast<E *>(&d);
    std::cout << (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
    }


    --
    VH
    Vaclav Haisman, Sep 17, 2010
    #3
  4. Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    Vaclav Haisman wrote:
    > The following gives me false with codepad.org:
    >
    > #include <iostream>
    >
    > struct A
    > {
    > virtual ~A ()
    > { }
    > };
    >
    > struct C
    > {
    > virtual ~C ()
    > { }
    > };
    >
    > struct B : C, A
    > { };
    >
    > struct E : A
    > { };
    >
    > struct D : E, B
    > { };
    >
    > int
    > main ()
    > {
    > D d;
    > A * aPtr = static_cast<E *>(&d);
    > std::cout << (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
    > }


    This code has undefined behavior. static_cast<B*>(aPtr) is invalid
    because the instance of A in aPtr is not a superclass of type B. It is a
    superclass of type E instead.

    Of course, dynamic_cast does not fail on this cross cast.


    Marcel
    Marcel Müller, Sep 17, 2010
    #4
  5. Pavel

    Pavel Guest

    Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    Vaclav Haisman wrote:
    > Pavel wrote, On 17.9.2010 13:33:
    >> Let us assume that A and B are classes, the variable aPtr has type A*, and
    >> the code containing the following assert statement compiles without error:
    >>
    >> assert(!dynamic_cast<B*>(aPtr)
    >> || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));
    >>
    >>
    >> Can A and B be defined in a way that the assertion would fail?

    > The following gives me false with codepad.org:
    >
    > #include<iostream>
    >
    > struct A
    > {
    > virtual ~A ()
    > { }
    > };
    >
    > struct C
    > {
    > virtual ~C ()
    > { }
    > };
    >
    > struct B : C, A
    > { };
    >
    > struct E : A
    > { };
    >
    > struct D : E, B
    > { };
    >
    > int
    > main ()
    > {
    > D d;
    > A * aPtr = static_cast<E *>(&d);
    > std::cout<< (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
    > }
    >
    >

    Thanks so much Vaclav!

    I felt something was fishy in that assumption in the code I was reading
    but could not exactly understand what was that.

    -Pavel
    Pavel, Sep 18, 2010
    #5
  6. Pavel

    James Kanze Guest

    On Sep 17, 12:33 pm, Pavel
    <> wrote:
    > Let us assume that A and B are classes, the variable aPtr has type A*,
    > and the code containing the following assert statement compiles without
    > error:


    > assert(!dynamic_cast<B*>(aPtr)
    > || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));


    > Can A and B be defined in a way that the assertion would fail?


    I don't think so off hand, but it's certainly possible to define
    the classes in such a way that the static_cast won't be legal
    (although the dynamic_cast is).

    --
    James Kanze
    James Kanze, Sep 18, 2010
    #6
  7. Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    Marcel Müller wrote, On 17.9.2010 22:39:
    > Vaclav Haisman wrote:
    >> The following gives me false with codepad.org:
    >>
    >> #include <iostream>
    >>
    >> struct A
    >> {
    >> virtual ~A ()
    >> { }
    >> };
    >>
    >> struct C
    >> {
    >> virtual ~C ()
    >> { }
    >> };
    >>
    >> struct B : C, A
    >> { };
    >>
    >> struct E : A
    >> { };
    >>
    >> struct D : E, B
    >> { };
    >>
    >> int
    >> main ()
    >> {
    >> D d;
    >> A * aPtr = static_cast<E *>(&d);
    >> std::cout << (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr));
    >> }

    >
    > This code has undefined behavior. static_cast<B*>(aPtr) is invalid because
    > the instance of A in aPtr is not a superclass of type B. It is a superclass
    > of type E instead.
    >
    > Of course, dynamic_cast does not fail on this cross cast.

    I did not realise it was UB but it does make sense. Though that's maybe what
    the assert is about, possibly detecting UB, however fragile/undefined it
    might be.

    --
    VH
    Vaclav Haisman, Sep 18, 2010
    #7
  8. Pavel

    Pavel Guest

    Re: Is the result of valid dynamic cast always equal to the resultof correspondent static cast?

    James Kanze wrote:
    > On Sep 17, 12:33 pm, Pavel
    > <> wrote:
    >> Let us assume that A and B are classes, the variable aPtr has type A*,
    >> and the code containing the following assert statement compiles without
    >> error:

    >
    >> assert(!dynamic_cast<B*>(aPtr)
    >> || (dynamic_cast<B*>(aPtr) == static_cast<B*>(aPtr)));

    >
    >> Can A and B be defined in a way that the assertion would fail?

    >
    > I don't think so off hand, but it's certainly possible to define
    > the classes in such a way that the static_cast won't be legal
    > (although the dynamic_cast is).
    >
    > --
    > James Kanze

    Thanks James! Vaclav gave a good example in his above post. I tend to
    forget about a possibility to have more than one identical base class
    because I don't use it often. I just remembered the code should not have
    relied on the above condition in general but could not recall why.

    -Pavel
    Pavel, Sep 19, 2010
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sam
    Replies:
    4
    Views:
    463
    The Directive
    Jan 13, 2004
  2. Sunner Sun

    Does sizeof(char) always equal to 1?

    Sunner Sun, May 22, 2005, in forum: C Programming
    Replies:
    9
    Views:
    757
    Jack Klein
    May 23, 2005
  3. arnuld

    why (getchar() != EOF) always equal to 1

    arnuld, Mar 8, 2007, in forum: C Programming
    Replies:
    12
    Views:
    712
    Mark McIntyre
    Mar 9, 2007
  4. Michael Tan
    Replies:
    32
    Views:
    940
    Ara.T.Howard
    Jul 21, 2005
  5. anish kumar
    Replies:
    13
    Views:
    113
Loading...

Share This Page