Topic: Interpretation of old-style casts in templates


Author: ken@digitas.org (Ken Shan)
Date: 1996/12/01
Raw View
I know this is not terribly important since it's deprecated anyway,
but I'm just curious...

    struct A { int a; };
    struct B { int b; };
    struct C: A, B { };

    template <class T>
    B *f(T t)
    {
        return (B *)t;
    }

    // ...
    A *pa;
    B *pb;
    C *pc;
    f(pa);      // obviously reinterpret_cast<B *>(pa)
    f(pb);      // obviously just pb
    f(pc);      // what's the interpretation for this?

I.e., should f(pc) be equivalent to reinterpret_cast<B *>(pc) (to be
consistent with the interpretation if T were any random type) or
static_cast<B *>(pc) (what would result if T is replaced with C *
throughout the definition of f())?

--
blue | Ken; Shan, Chung-chieh; Sian7, Tiong1-kiat8; ken@digitas.harvard.edu.
 ()  | Your code today becomes the mind tomorrow:  Your plan its means,
 /\  | your dream its ends, your ideal its elegance.  Hack on.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/12/02
Raw View
Ken Shan writes:

>     struct A { int a; };
>     struct B { int b; };
>     struct C: A, B { };

>     template <class T>
>     B *f(T t)
>     {
>         return (B *)t;
>     }

>     C *pc;
>     f(pc);      // what's the interpretation for this?

> I.e., should f(pc) be equivalent to reinterpret_cast<B *>(pc) (to be
> consistent with the interpretation if T were any random type) or
> static_cast<B *>(pc) (what would result if T is replaced with C *
> throughout the definition of f())?

There's no reason to believe (B*) should be equivalent to
reinterpret_cast<B*>.  If you want a reinterpret_cast or a
static_cast, write this in the program explicitly.  Only use an
old-style cast if you wish the compiler to do the best it can to do a
safe conversion.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ken@digitas.org (Ken Shan)
Date: 1996/12/03
Raw View
Alexandre Oliva (oliva@dcc.unicamp.br) wrote:

> There's no reason to believe (B*) should be equivalent to
> reinterpret_cast<B*>.  If you want a reinterpret_cast or a
> static_cast, write this in the program explicitly.  Only use an
> old-style cast if you wish the compiler to do the best it can to do a
> safe conversion.

I know I shouldn't use old-style casts, and I don't; I'm just
wondering what the current draft standard specifies...

--
blue | Ken; Shan, Chung-chieh; Sian7, Tiong1-kiat8; ken@digitas.harvard.edu.
 ()  | Your code today becomes the mind tomorrow:  Your plan its means,
 /\  | your dream its ends, your ideal its elegance.  Hack on.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/12/04
Raw View
Ken Shan <ken@digitas.org> wrote in article
<57revl$olm@decaxp.harvard.edu>...
> I know this is not terribly important since it's deprecated anyway,
> but I'm just curious...

Are old-style casts deprecated? I didn't think they were yet.

>     struct A { int a; };
>     struct B { int b; };
>     struct C: A, B { };
>
>     template <class T> B* f(T t)
>     { return (B*) t; }
>
>     A *pa; B *pb; C *pc;
>     f(pa);      // obviously reinterpret_cast<B *>(pa) [not quite right]
>     f(pb);      // obviously just pb
>     f(pc);      // what's the interpretation for this?
>
> I.e., should f(pc) be equivalent to reinterpret_cast<B *>(pc) (to be
> consistent with the interpretation if T were any random type) or
> static_cast<B *>(pc) (what would result if T is replaced with C *
> throughout the definition of f())?

I think you misinterpreted Alexandre Oliva's reply to your article. His
point wasn't so much that you shouldn't use old-style casts as much as that
they don't do exactly what you assumed in your article. Old-style casts
don't necessarily mean reinterpret_cast<>; but they might accomplish the
same thing in some cases.

The fact that the old-style cast occurs in a template means nothing. The
three instantiations of your template function contain the equivalent of

 A* t; return (B*) t;
 B* t; return (B*) t;
 C* t; return (B*) t;

These old-style casts behave they same way they always have in C++. Since
A* and B* are unrelated static types, the bit-pattern of one is merely
reinterpreted as the other, with implementation-defined effects. Since B*
and B* are the same type, the second cast performs no operation. Since C*
and B* are related to each other by derivation, the third cast performs a
conversion to base-class subobject (which is an implicit conversion in that
situation anyway). If B were derived from D and you added

 D* t; return (B*) t;

then the cast would perform a (static) downcast from D* to B*, whether the
object is really a B or not. Notice that the meaning of the cast changes
depending on the types in the instantiation. That's a possible way to
confuse maintainers of code, but it might be just what you wanted.

Keep in mind that each of the new-style casts has a particular, limited
operation, with very little room for interpretation on the compiler's part.
Old-style casts are a sort of "best effort" by the compiler to figure out
what you meant to do. Thus Alexandre's statement to use reinterpret_cast<>
when you need that and to use old-style casts when you need those. Also
keep in mind that there are a couple of unsafe casts (for example, between
private base classes and derived classes) that _only_ old-style casts can
accomplish.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/12/04
Raw View
Ken Shan writes:

> Alexandre Oliva (oliva@dcc.unicamp.br) wrote:
>> There's no reason to believe (B*) should be equivalent to
>> reinterpret_cast<B*>.  If you want a reinterpret_cast or a
>> static_cast, write this in the program explicitly.  Only use an
>> old-style cast if you wish the compiler to do the best it can to do a
>> safe conversion.

> I know I shouldn't use old-style casts, and I don't; I'm just
> wondering what the current draft standard specifies...

The standard specifies that the following alternatives will be tried,
in this order, and the first one to succeed will be taken:

  --a const_cast (_expr.const.cast_),

  --a static_cast (_expr.static.cast_),

  --a static_cast followed by a const_cast,

  --a reinterpret_cast (_expr.reinterpret.cast_), or

  --a reinterpret_cast followed by a const_cast,

(from [expr.cast] paragraph 5)

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]