Topic: in response to "Informal Defect Report: static_cast (5.2.9/2)" by Attila Feher


Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Tue, 17 Sep 2002 17:14:17 +0000 (UTC)
Raw View
In article <3D870E94.BFA0D362@lmf.ericsson.se>, Attila Feher
<Attila.Feher@lmf.ericsson.se> writes
>That bothers me as well.  I mean the T(e) rule does not work - and this
>rule does not seem to work either.  I just wonder that all those
>language gurus here did not come up with _any_ answer neither on this
>qestion or my question about what does the "interpreted" mean for C
>style casts.  Kinda frightening that in csc++ there is not one single
>soul who understands casts... :-(

Well we do advise that people try not to use them:-) My description of a
cast is an instruction to the compiler : "Do this because I know what I
am doing even if you do not." So if you do not know what you are doing,
do not do it.:-)


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: n.borissov@sympatico.ca ("Nikolai Borissov")
Date: Sun, 15 Sep 2002 22:57:20 +0000 (UTC)
Raw View
This is a multi-part message in MIME format.

------=_NextPart_000_0467_01C25C3A.D94EBDB0
Content-Type: text/plain;
 charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Attila Feher   wrote
> Looking into this sentence, especially this part:
>
> "The static_cast operator converts between related types"
>
> it suggests that a static_cast will not convert in more than one step!
> The examples support this understanding.  The above Widget code =
requires
> two step conversion: convert int to Widget, then binding the =
reference.
> This is clearly two steps.  (What is confusing is that the same =
happens
> in case of int to a reference to a constant double, and that works.)

To my opinion, the conversion between related types does not mean =
one-step conversion, whatever reasonable meaning to a step we can =
assign.

Here is a  set of static casts which is accepted by Comeau C++ compiler.
(Sorry there is some guessing about conversion steps, but I don't see =
any 1-step reasonable explanation at all)

#include <new>

struct A {};
struct DerA: public A {};
struct OpDerA { operator DerA() const {return DerA();};};
struct B {};
struct DerB: public B {};
struct OpDerB { operator DerB() const {return DerB();};};
struct Widget
{Widget();
  Widget(int);
  Widget(const A&);
  Widget(const B);
};
struct  DerWidget: public Widget {};
struct OpDerWidget { operator DerWidget&() const {return *new =
DerWidget;};};

int main()
{=20
static_cast<Widget>(5.0);
// 1) 5.0 -> temp int=20
// 2) temp int -> Widget(int) -> taget Widget object

static_cast<Widget>(OpDerA());
// 1) OpDerA operator -> temp DerA object
// 2) temp DerA -> reference to temp DerA=20
// 3) reference to temp DerA -> reference to subobject A
// 4) reference to subobject A -> reference to const subobject A
// 5) reference to const subobject A -> Widget(const A&) -> target =
Widget object

static_cast<Widget>(OpDerB());
// 1) OpDerB operator -> temp DerB object
// 2) temp DerB -> reference to temp DerB
// 3) reference to temp DerB -> reference to subobject B
// 4) reference to subobject B -> reference to const subobject B
// 5) reference to const subobject B -> class B copy constructor =
(default) -> temp object B
// 6) temp object B -> const temp object B
// 7) const temp object B -> Widget(const B) -> target Widget object

static_cast<Widget>(OpDerWidget());
// 1) OpDerWidget operator -> reference to DerWidget object
// 2) reference to DerWidget object -> reference to Widget subobject
// 3) reference to Widget subobject -> reference to const Widget =
subobject
// 4) reference to const Widget subobject -> Widget default copy =
constructor -> target Widget object

static_cast<const Widget&>(DerWidget());
// 1) temp DerWidget object -> reference to temp DerWidget object
// 2) reference to temp DerWidget object -> reference to Widget =
subobject
// 3) reference to Widget subobject -> reference to const Widget =
subobject (target)

static_cast<const Widget&>(OpDerWidget());
// 1) OpDerWidget operator -> reference to DerWidget object
// 2) reference to DerWidget object  ->  reference to Widget subobject
// 3) reference to Widget subobject -> reference to const Widget =
subobject (target)

return 0;
}


Nikolai Borissov


------=_NextPart_000_0467_01C25C3A.D94EBDB0
Content-Type: text/html;
 charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2719.2200" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>
<DIV>Attila Feher&nbsp;&nbsp; wrote<BR>&gt; Looking into this sentence,=20
especially this part:<BR>&gt;<BR>&gt; "The static_cast operator converts =
between=20
related types"<BR>&gt;<BR>&gt; it suggests that a static_cast will not =
convert=20
in more than one step!<BR>&gt; The examples support this =
understanding.&nbsp;=20
The above Widget code requires<BR>&gt; two step conversion: convert int =
to=20
Widget, then binding the reference.<BR>&gt; This is clearly two =
steps.&nbsp;=20
(What is confusing is that the same happens<BR>&gt; in case of int to a=20
reference to a constant double, and that works.)</DIV>
<DIV>&nbsp;</DIV>
<DIV>To my opinion, the conversion between related types does not mean =
one-step=20
conversion, whatever reasonable meaning to a step we can assign.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Here is a&nbsp; set of&nbsp;static casts&nbsp;which&nbsp;is =
accepted by=20
Comeau C++ compiler.</DIV>
<DIV>(Sorry there is some guessing about conversion steps, but I don't =
see any=20
1-step reasonable explanation at all)</DIV>
<DIV>&nbsp;</DIV>
<DIV>#include &lt;new&gt;</DIV>
<DIV>&nbsp;</DIV>
<DIV>struct&nbsp;A {};</DIV>
<DIV>struct DerA: public A&nbsp;{};</DIV>
<DIV>
<DIV>struct OpDerA {&nbsp;operator DerA() const {return=20
DerA();};};</DIV>struct&nbsp;B {};</DIV>
<DIV>struct&nbsp;DerB:&nbsp;public B {};</DIV>
<DIV>struct OpDerB {&nbsp;operator DerB() const {return =
DerB();};};</DIV>
<DIV>struct Widget</DIV>
<DIV>{Widget();</DIV>
<DIV>&nbsp;&nbsp;Widget(int);</DIV>
<DIV>&nbsp; Widget(const A&amp;);</DIV>
<DIV>&nbsp; Widget(const B);<BR>};</DIV>
<DIV>struct&nbsp; DerWidget: public Widget {};</DIV>
<DIV>struct OpDerWidget {&nbsp;operator DerWidget&amp;() const {return =
*new=20
DerWidget;};};</DIV>
<DIV>&nbsp;</DIV>
<DIV>int main()</DIV>
<DIV>{&nbsp;</DIV>
<DIV>static_cast&lt;Widget&gt;(5.0);</DIV>
<DIV>// 1) 5.0 -&gt; temp int=20
<DIV>//&nbsp;2) temp int -&gt; Widget(int) -&gt; taget Widget =
object</DIV>
<DIV>&nbsp;</DIV>
<DIV>static_cast&lt;Widget&gt;(OpDerA());</DIV></DIV>
<DIV>// 1) OpDerA operator -&gt; temp DerA object</DIV>
<DIV>// 2) temp DerA -&gt;&nbsp;reference to&nbsp;temp DerA </DIV>
<DIV>// 3) reference to&nbsp;temp DerA -&gt; reference to&nbsp;subobject =
A</DIV>
<DIV>// 4) reference to&nbsp;subobject A -&gt; reference to const =
subobject=20
A</DIV>
<DIV>// 5)&nbsp;reference to const subobject A&nbsp;-&gt; Widget(const =
A&amp;)=20
-&gt; target Widget object</DIV>
<DIV>&nbsp;</DIV>
<DIV>static_cast&lt;Widget&gt;(OpDerB());</DIV>
<DIV>// 1) OpDerB operator -&gt; temp DerB object</DIV>
<DIV>// 2) temp DerB -&gt; reference to&nbsp;temp DerB</DIV>
<DIV>// 3) reference to&nbsp;temp DerB -&gt; reference to&nbsp;subobject =
B</DIV>
<DIV>// 4) reference to&nbsp;subobject B -&gt; reference to const =
subobject=20
B</DIV>
<DIV>// 5)&nbsp;reference to const subobject B -&gt;&nbsp;class B copy=20
constructor (default) -&gt; temp object B</DIV>
<DIV>// 6) temp object B -&gt; const temp object B</DIV>
<DIV>// 7) const temp object B -&gt; Widget(const B) -&gt; target Widget =

object</DIV>
<DIV>&nbsp;</DIV>
<DIV>static_cast&lt;Widget&gt;(OpDerWidget());</DIV>
<DIV>// 1) OpDerWidget operator -&gt; reference to DerWidget =
object</DIV>
<DIV>// 2) reference to DerWidget object -&gt; reference to&nbsp;Widget=20
subobject</DIV>
<DIV>// 3) reference to Widget subobject -&gt; reference to const Widget =

subobject</DIV>
<DIV>// 4)&nbsp;reference to const Widget subobject&nbsp;-&gt; Widget =
default=20
copy constructor -&gt; target Widget object</DIV>
<DIV>&nbsp;</DIV>
<DIV>static_cast&lt;const Widget&amp;&gt;(DerWidget());</DIV>
<DIV>// 1) temp DerWidget object -&gt; reference to temp DerWidget =
object</DIV>
<DIV>// 2) reference to temp DerWidget object -&gt; reference to Widget=20
subobject</DIV>
<DIV>// 3) reference to Widget subobject -&gt; reference to const Widget =

subobject (target)</DIV>
<DIV>&nbsp;</DIV>
<DIV>static_cast&lt;const Widget&amp;&gt;(OpDerWidget());</DIV>
<DIV>// 1) OpDerWidget operator -&gt; reference to&nbsp;DerWidget =
object</DIV>
<DIV>// 2) reference to&nbsp;DerWidget object&nbsp; =
-&gt;&nbsp;&nbsp;reference=20
to&nbsp;Widget subobject</DIV>
<DIV>// 3) reference to Widget subobject -&gt; reference to const Widget =

subobject (target)</DIV>
<DIV>&nbsp;</DIV>
<DIV>return 0;</DIV>
<DIV>}</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV>Nikolai Borissov</DIV>
<DIV>&nbsp;</DIV></FONT></DIV></BODY></HTML>

------=_NextPart_000_0467_01C25C3A.D94EBDB0--

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]