Topic: static_cast question
Author: AllanW@my-dejanews.com
Date: 1998/09/10 Raw View
In article <njKO7eSO4UCT-pn2-dPKXcmWYOdBe@pn-dialkn1-13.primary.net>,
peter.garner@toward.com (Crazy Pete) wrote:
>
> On Wed, 9 Sep 1998 07:03:25, AllanW@my-dejanews.com wrote:
>
> > > Some purists might demand that the data be received as a string of bytes
> > > which are then processed by a constructor to create a proper C++ object,
> > > with RTTI and virtual functions, but that would be hopelessly inefficient
in
> > > a real time application.
> >
> > Hopelessly inefficient? I think not. The virtual-table pointer takes on
> > the role of your type byte. This is extremely similar in terms of space
> > and time, with the added bonus of being supported automatically by the
> > compiler.
>
> I THINK he meant what is inefficient is the extra copying and overhead
> of calling a constructor, not the overhead of virtual functions. ;-)
But, again, this would have to happen anyway. Either you stuff the data
into a struct, or you pass it to a constructor. The results are similar.
Even if that's completely unacceptable (and I would have to ask WHY?),
you could construct classes which contain pointers to the existing
structure. By using class types, you could still have virtual functions
which are superior to mega-switch statements.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Martijn Lievaart" <nobody@orion.nl>
Date: 1998/09/08 Raw View
Francis Glassborow wrote in message ...
>
>In article <6spofr$64f$1@engnews1.eng.sun.com>, Steve Clamage
><stephen.clamage@sun.com> writes
>>That exact example probably would work, although the standard does
>>not assure you that it will. (The results are undefined.)
>>
>>You are telling the compiler that you are calling a Derived member
>>function on a Derived object when the object is really a Base object.
>>In general, that can't be expected to have a good result.
>
>I find it very difficult to conceive of any situation where a derived
>class adds no data but only functionality (or over-rides existing
>functionality) where downcasting would fail.
>
(snip)
>
>IMHO the standard may declare this as undefined behaviour, but I would
>want something more than that from an implementor if they broke my code
>this way. I think that any such implementatio would have to be
>deliberately malicious.
>
Well how about a compiler that adds a debugging aid: the first bytes of any
object hold a pointer to RTTI. (This has nothing to do with RTTI as defined
in the standard). Now the derived object must be bigger than the base
object, as the RTTI bytes for the derived object must precede the base
object. The derived object itself has these bytes as well at the start of
the object, pointing to the base RTTI.
Contrived? Maybe. Possible? Sure. Malicious? No. Usefull? Hmmm.
I would place this trick in the catagory "if you really, really must do it,
don't tell your mum". It will never generate industrial strength code and
usually there are other ways to arrive at the same result. (See also the
thread "Who needs friends").
Martijn (see sig for real address)
--
My email address is intentionally invalid against spam
reply to mlievaart at orion in nl
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Jim Cobban" <Jim.Cobban.jcobban@nt.com>
Date: 1998/09/08 Raw View
In article <6sndfm$9hs$1@pigpen.csrlink.net>,
John Potter <jpotter@falcon.lhup.edu> wrote:
>
>Maybe I don't understand your statement, but I think that it should
>never work unless the above "you know what you're doing" is true.
>
>class B {
> };
>class D : public B {
> void somethingNew ();
> };
>void foobar () {
> B b;
> static_cast<D&>(b).somethingNew();
> }
>
>That is well-formed but I would not expect it to work. Did I miss
>something?
My work is almost entirely with communications protocols. Since the data
structures in such protocols must be transmitted between independent memory
spaces it is not feasible to use the normal C++ polymorphism techniques,
such as virtual functions. The sending function cannot possibly know the
address of the proper virtual function on the receiving machine. They may
not even have the same machine architecture. In these protocols therefore
every object tends to contain a type field, which indicates the format of
the following data. The receiving application initially only knows the
general class of the data, say that the first byte contains the type
information. It must interrogate that byte and then cast the object pointer
or reference to the actual type of the object. dynamic_cast is not
available in that situation, and reinterpret_cast would be overkill because
the conversion is well defined, as long as the program "knows what it is
doing", which it does because it has interrogated the type byte. So
static_cast it is.
Some purists might demand that the data be received as a string of bytes
which are then processed by a constructor to create a proper C++ object,
with RTTI and virtual functions, but that would be hopelessly inefficient in
a real time application.
--
Jim Cobban | jcobban@nortel.ca | Phone: (613) 763-8013
Nortel (MCS) | | FAX: (613) 763-5199
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/09 Raw View
In article <6t40u2$56p@bcarh8ab.ca.nortel.com>,
"Jim Cobban" <Jim.Cobban.jcobban@nt.com> wrote:
> My work is almost entirely with communications protocols. Since the data
> structures in such protocols must be transmitted between independent memory
> spaces it is not feasible to use the normal C++ polymorphism techniques,
> such as virtual functions. The sending function cannot possibly know the
> address of the proper virtual function on the receiving machine. They may
> not even have the same machine architecture. In these protocols therefore
> every object tends to contain a type field, which indicates the format of
> the following data. The receiving application initially only knows the
> general class of the data, say that the first byte contains the type
> information. It must interrogate that byte and then cast the object pointer
> or reference to the actual type of the object. dynamic_cast is not
> available in that situation, and reinterpret_cast would be overkill because
> the conversion is well defined, as long as the program "knows what it is
> doing", which it does because it has interrogated the type byte. So
> static_cast it is.
>
> Some purists might demand that the data be received as a string of bytes
> which are then processed by a constructor to create a proper C++ object,
> with RTTI and virtual functions, but that would be hopelessly inefficient in
> a real time application.
Hopelessly inefficient? I think not. The virtual-table pointer takes on
the role of your type byte. This is extremely similar in terms of space
and time, with the added bonus of being supported automatically by the
compiler.
Virtual functions are implemented (indeed, I've come to conclude that
the compiler *has* to implement them this way) in a manner equivalent
to the best code that an expert C programmer could produce, which is
at least slightly better than an average C programmer could produce.
By "better" I mean more efficient in terms of speed with very little
lost in terms of space. Even if you are an expert C programmer,
capable of producing code of the same high quality manually, you
should prefer the virtual call mechanism because it is cleaner and
especially less error prone.
Someplace in your code you take received data and pump it into an
object, or at least a struct. At that point in the code, you can
use the type byte to call the correct constructor; by doing this,
you will free yourself of many switch() statements elsewhere in
the code.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: peter.garner@toward.com (Crazy Pete)
Date: 1998/09/09 Raw View
On Wed, 9 Sep 1998 07:03:25, AllanW@my-dejanews.com wrote:
> > Some purists might demand that the data be received as a string of bytes
> > which are then processed by a constructor to create a proper C++ object,
> > with RTTI and virtual functions, but that would be hopelessly inefficient in
> > a real time application.
>
> Hopelessly inefficient? I think not. The virtual-table pointer takes on
> the role of your type byte. This is extremely similar in terms of space
> and time, with the added bonus of being supported automatically by the
> compiler.
I THINK he meant what is inefficient is the extra copying and overhead
of calling a constructor, not the overhead of virtual functions. ;-)
Peace
Peter
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/04 Raw View
In article <6sndfm$9hs$1@pigpen.csrlink.net>, John Potter
<jpotter@falcon.lhup.edu> writes
>class B {
> };
>class D : public B {
public:
> void somethingNew ();
> };
>void foobar () {
> B b;
> static_cast<D&>(b).somethingNew();
> }
>That is well-formed but I would not expect it to work. Did I miss
>something?
I would expect it to work, because I cannot see any reason for it not to
do so.
--
Francis Glassborow
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/09/04 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:
>In article <6sndfm$9hs$1@pigpen.csrlink.net>, John Potter
><jpotter@falcon.lhup.edu> writes
>>class B {
>> };
>>class D : public B {
>public:
>> void somethingNew ();
>> };
>>void foobar () {
>> B b;
>> static_cast<D&>(b).somethingNew();
>> }
>>That is well-formed but I would not expect it to work. Did I miss
>>something?
>I would expect it to work, because I cannot see any reason for it not to
>do so.
That exact example probably would work, although the standard does
not assure you that it will. (The results are undefined.)
You are telling the compiler that you are calling a Derived member
function on a Derived object when the object is really a Base object.
In general, that can't be expected to have a good result.
--
Steve Clamage, stephen.clamage@sun.com
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/05 Raw View
In article <6spofr$64f$1@engnews1.eng.sun.com>, Steve Clamage
<stephen.clamage@sun.com> writes
>That exact example probably would work, although the standard does
>not assure you that it will. (The results are undefined.)
>
>You are telling the compiler that you are calling a Derived member
>function on a Derived object when the object is really a Base object.
>In general, that can't be expected to have a good result.
I find it very difficult to conceive of any situation where a derived
class adds no data but only functionality (or over-rides existing
functionality) where downcasting would fail.
The derived class is required to contain a base class sub-object and, in
this case, there is nothing else that it can contain.
Actually there is one possible area where doubt lurks in my mind and
that is where the immediate base class includes a virtual base. But
even then I cannot see any reason why the derived class should change
the layout of its data.
IMHO the standard may declare this as undefined behaviour, but I would
want something more than that from an implementor if they broke my code
this way. I think that any such implementatio would have to be
deliberately malicious.
--
Francis Glassborow
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alex Gontmakher <gsasha@cs.technion.ac.il>
Date: 1998/09/05 Raw View
> 'static_cast' instead of 'dynamic_cast'
> for a cast Base* --> Derived*
Of course this is allowed. The difference is, with the dynamic_cast the
conversion is checked in the run-time, while with static_cast the compiler
assumes you know what you're doing.
Anyway, static_cast should be used exceptionally rarely (even more rare than
static_cast), exactly because the compiler has no way to prevent you from
doing errors (and in C++, there is almost always a way to avoid static_cast).
It is sometimes useful to use static_cast inside templates, where it is a
very small and verifiable code.
For instance (the idea is from Effective C++) if you have an implementation
of class list which stores void ptrs, you wrap it inside an implementation of
list which requires some type T (which is the parameter of template), thus
ensuring type safety. And please note that the static cast is thus hidden
deeply inside! It is not in the application code.
Sasha
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de>
Date: 1998/09/03 Raw View
Hi.
The egcs-1.0.2 (the gcc-2.8.1 too) does compile,
without any warning, the code below.
'static_cast' instead of 'dynamic_cast'
for a cast Base* --> Derived*
Is this allowed?
class A {
public:
virtual ~A() {}
};
class B : public A {
public:
void fun() {}
};
void func(A* pA)
{
B* pB = static_cast<B*>(pA); // NOT dynamic_cast!
pB->fun();
}
Ryszard Kabatek
--
Martin-Luther University Halle-Wittenberg
Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany
Tel. +49 3461 46 2487 Fax. +49 3461 46 2129
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/09/03 Raw View
On 3 Sep 1998 16:32:46 GMT, Ryszard Kabatek
>The egcs-1.0.2 (the gcc-2.8.1 too) does compile,
>without any warning, the code below.
>
>'static_cast' instead of 'dynamic_cast'
>for a cast Base* --> Derived*
I've seen this done in Stroustrup III, so it must be allowed.
It's useful for the following case: Suppose you have a class that
contains an array of Base* objects, and suppose that the class
maintains the constraint that each object has the same dynamic
type. That is, all objects are Derived1 objects, or all are
Derived2 objects. Then you can do a typeid on any object to
figure out the dynamic type of every object. Then instead of
doing a typeid or dynamic_cast on each object in the array, you
just do a static_cast. Faster, but risky.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/09/03 Raw View
Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> writes:
> The egcs-1.0.2 (the gcc-2.8.1 too) does compile,
> without any warning, the code below.
> 'static_cast' instead of 'dynamic_cast'
> for a cast Base* --> Derived*
> Is this allowed?
Yup. static_cast can perform base to derived casts, as long as the
base class is not a virtual base class. [expr.static.cast]/5
It assumes you know what you're doing, i.e., the Base* really points
to an object whose dynamic type is Derived.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/09/03 Raw View
In article <oremtt2exw.fsf@tiete.dcc.unicamp.br>, Alexandre Oliva
<oliva@dcc.unicamp.br> writes
>Yup. static_cast can perform base to derived casts, as long as the
>base class is not a virtual base class. [expr.static.cast]/5
>
>It assumes you know what you're doing, i.e., the Base* really points
>to an object whose dynamic type is Derived.
Maybe I am mistaken, but I think it should also work if the derived
class only includes extra member functions but no extra data. I would
be interested to know if that assumption is always justified.
--
Francis Glassborow
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/09/04 Raw View
Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> writes:
>The egcs-1.0.2 (the gcc-2.8.1 too) does compile,
>without any warning, the code below.
>'static_cast' instead of 'dynamic_cast'
>for a cast Base* --> Derived*
>Is this allowed?
Yes, but the result is not guaranteed to be meaningful. It has
the same semantics as an old-style cast when used this way.
You can't cast down past a virtual base class, for instance,
or "sideways" in a multiply-inherited hierarchy.
If Base is not polymorphic, you can't use dynamic_cast for
downcasts, so static_cast is your only option. It's then up to
you to determine whether the cast is safe.
--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1998/09/04 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
: In article <oremtt2exw.fsf@tiete.dcc.unicamp.br>, Alexandre Oliva
: <oliva@dcc.unicamp.br> writes
: >Yup. static_cast can perform base to derived casts, as long as the
: >base class is not a virtual base class. [expr.static.cast]/5
: >
: >It assumes you know what you're doing, i.e., the Base* really points
: >to an object whose dynamic type is Derived.
: Maybe I am mistaken, but I think it should also work if the derived
: class only includes extra member functions but no extra data. I would
: be interested to know if that assumption is always justified.
Maybe I don't understand your statement, but I think that it should
never work unless the above "you know what you're doing" is true.
class B {
};
class D : public B {
void somethingNew ();
};
void foobar () {
B b;
static_cast<D&>(b).somethingNew();
}
That is well-formed but I would not expect it to work. Did I miss
something?
John
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]