C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

typecasting the base class to derived class.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
cman
Guest





PostPosted: Fri Feb 20, 2004 8:53 pm    Post subject: typecasting the base class to derived class. Reply with quote



#include <stdio.h>

class Base
{
public:
Base()
{
printf("Base()n");
}
~Base()
{
printf("~Base()n");
}
};

class Derived:public Base
{
public:
Derived()
{
printf("Derived()n");
}
void myConst() const
{
printf("Derived's myConst function x=%d",x);
}
~Derived()
{
printf("~Derived()n");
}
int x;
};

main()
{
Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;
dptr->myConst();
delete dptr;
}


In the above code "dptr->myConst()" succeeds without giving any error
on Solaris, but generates an exception when ran on Winodws after
compiling in VC++

My Question is Why does it not fail? since typecasting should not
define x... this call should fail. I replaced "x" with "x[1024]" and
then used the last element in the array above, to isolate the
possiblity of having a fluke. But it still worked !

Thanks.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Tutone
Guest





PostPosted: Sat Feb 21, 2004 10:49 am    Post subject: Re: typecasting the base class to derived class. Reply with quote




"cman" <complangman (AT) yahoo (DOT) com> wrote:

Quote:
#include <stdio.h

class Base
{
public:
Base()
{
printf("Base()n");
}

Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.

Quote:
~Base()
{
printf("~Base()n");
}
};

class Derived:public Base
{
public:
Derived()
{
printf("Derived()n");
}
void myConst() const
{
printf("Derived's myConst function x=%d",x);
}
~Derived()
{
printf("~Derived()n");
}
int x;
};

main()

main returns int. Always. Please see the FAQ.

Quote:
{
Derived *dptr;
dptr=(Derived *)new Base();

OK, so you've casted it to something it's not.
Probably better to get in the habit of using a
static_cast<> in these circumstances...

Quote:
dptr->x=10;

undefined behavior.

Quote:
dptr->myConst();

undefined behavior.

Quote:
delete dptr;
}


In the above code "dptr->myConst()" succeeds
without giving any error
on Solaris, but generates an exception when ran on
Winodws after
compiling in VC++

My Question is Why does it not fail?

Your program has undefined behavior. "Appearing to
work" and "crashing the computer" both fall in the
category of undefined behavior. In fact, "appearing
to work the first 5000 times I run it, then crashing
on the 5001st time" also falls in the category of
undefined behavior. Presumably what is actually
happening - although it is obviously
implementation-dependent - is that the computer is
trashing random memory when it assigns to the
nonexistent x member. On the Solaris, it so happens
that trashing that memory doesn't cause any
immediately visible effects - it may even be trashing
memory that didn't have anything important in it
anyway. On the Visual C++ platform, presumably you
weren't so lucky.

By the way, I don't know what you mean by "exception."
A C++ exception? A hardware exception? A .NET
structured exception? That is an overloaded term, and
you haven't provided enough info to determine which
meaning you intended. But I suppose that any of those
still falls in the category of undefined behavior.

Best regards,

Tom



__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Turkanis
Guest





PostPosted: Sat Feb 21, 2004 1:59 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote



"cman" <complangman (AT) yahoo (DOT) com> wrote in message:

<snip>

Quote:
main()
{
Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;
dptr->myConst();
delete dptr;
}

<snip>

Quote:
My Question is Why does it not fail?

It is undefined behavior, by 5.4/5 and 5.2.9/5. No diagnostic or
explosion is required.

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ulrich Eckhardt
Guest





PostPosted: Sat Feb 21, 2004 4:14 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

cman wrote:
Quote:
Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;

Undefined behaviour, all bets are off. Just don't do that.

Uli

--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Sat Feb 21, 2004 4:25 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
Quote:
"cman" <complangman (AT) yahoo (DOT) com> wrote:

#include
class Base
{
public:
Base()
{
printf("Base()n");
}

Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.

To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Sat Feb 21, 2004 6:23 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

Francis Glassborow wrote:
Quote:

In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:

#include
class Base
{
public:
Base()
{
printf("Base()n");
}

Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.

To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.


There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
stelios xanthakis
Guest





PostPosted: Sun Feb 22, 2004 1:47 am    Post subject: Re: typecasting the base class to derived class. Reply with quote

Pete Becker <petebecker (AT) acm (DOT) org> wrote


Quote:
There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.

The problem is an illegal downcast. This is why the new
C++ casts (static/reintepret/dynamic/const) were invented
by its designers: they can warn on such errors.

As long as a base object is casted to a derrived object,
the program is ill. It may not crash because accedentially
the objects have the same size, but it is not ok.

sx

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Sun Feb 22, 2004 5:31 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

stelios xanthakis wrote:
Quote:

Pete Becker <petebecker (AT) acm (DOT) org> wrote


There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.

The problem is an illegal downcast.

Please don't snip context. I was replying to these assertions:

Quote:
Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.

To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.

Illegal downcasts are not involved here. The design issue raised here is
when classes should have virtual destructors.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Feb 23, 2004 7:41 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

Pete Becker <petebecker (AT) acm (DOT) org> wrote

Quote:
Francis Glassborow wrote:

In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:

#include
class Base
{
public:
Base()
{
printf("Base()n");
}

Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base pointer
to refer to a Derived object.

To be absolutely precise, if there is any chance that you will try
to delete a dynamic instance through a base-class pointer.

There's always a chance that someone will write incorrect code. The
true test is not probabilistic. It is whether the design of the base
class calls for deletion of derived types through base pointers.

Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what the
original poster did, and given the original problem (and not just the
bit of code you were responding to), one could argue that the "correct"
solution would have been to add a virtual destructor to Base, and to use
reinterpret_cast. That way, he would have gotten the exception or the
error he seems to want.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jim Melton
Guest





PostPosted: Tue Feb 24, 2004 3:28 am    Post subject: Re: typecasting the base class to derived class. Reply with quote

<kanze (AT) gabi-soft (DOT) fr> wrote

Quote:
Pete Becker <petebecker (AT) acm (DOT) org> wrote in message
news:<403786D3.5AE43460 (AT) acm (DOT) org>...
Francis Glassborow wrote:

In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>,
Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:

#include <stdio.h

class Base
{
public:
Base()
{
printf("Base()n");
}

Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base pointer
to refer to a Derived object.

To be absolutely precise, if there is any chance that you will try
to delete a dynamic instance through a base-class pointer.

There's always a chance that someone will write incorrect code. The
true test is not probabilistic. It is whether the design of the base
class calls for deletion of derived types through base pointers.

Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what the
original poster did, and given the original problem (and not just the
bit of code you were responding to), one could argue that the "correct"
solution would have been to add a virtual destructor to Base, and to use
reinterpret_cast. That way, he would have gotten the exception or the
error he seems to want.


OK, you lost me. The OP's problem was that he used a C-style cast, which
blindly does precisely what you tell it. I would have thought that
dynamic_cast would have been the correct solution (presuming any virtual
functions at all -- usually required to achieve polymorphism).

Here's my touchstone for C++-style casts:

static_cast - invoke defined conversion
const_cast - add/remove constness
dynamic_cast - typesafe down-cast
reinterpret_cast - DWIM (do what i mean): interpret the bits of the argument
as if they were the template type

Of the four, I think reinterpret_cast is the hardest to get right. But I
didn't think you would get any type-safety from it. Is it possible your
recommendation is a typo?
--
Opinions posted are those of the author.
My company doesn't pay me enough to speak for them.
</disclaimer>
--
Jim Melton
Software Architect, Fusion Programs
Lockheed Martin IS&S
(303) 971-3846




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
stelios xanthakis
Guest





PostPosted: Tue Feb 24, 2004 7:26 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

Pete Becker <petebecker (AT) acm (DOT) org> wrote

Quote:
stelios xanthakis wrote:

Pete Becker <petebecker (AT) acm (DOT) org> wrote


There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.

The problem is an illegal downcast.

Please don't snip context. I was replying to these assertions:


I'm sorry. Just wanted to point out what's really wrong before
the thread went too far.

Quote:
Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.

To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.

Illegal downcasts are not involved here. The design issue raised here is
when classes should have virtual destructors.

That would had been the case if the code was

Base *b = new Derrived;

The case:

Derrived *d = (Derrived*) new Base;

Is ill and because there are people reading clc++ who are not
experts, we wouldn't want to confuse this ill program with the
virtual dtors.

BTW, to contribute to the discussion, I think a virtual
destructor is also needed in this case:

class A { int x; };
class B { int y; };
class C : A, B { int z; };

int f ()
{
B *b = new C;
delete b;
}

Despite the fact that the classes have no dtors, a virtual dtor
must be present because the above crashes. How does the std
describes this? I don't know...

Cheers,

Stelios

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Feb 24, 2004 7:29 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

Jim Melton <jim.melton (AT) lmco (DOT) com> wrote

Quote:
Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base
pointer to refer to a Derived object.

To be absolutely precise, if there is any chance that you will
try to delete a dynamic instance through a base-class pointer.

There's always a chance that someone will write incorrect
code. The true test is not probabilistic. It is whether the design
of the base class calls for deletion of derived types through base
pointers.

Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what
the original poster did, and given the original problem (and not
just the bit of code you were responding to), one could argue that
the "correct" solution would have been to add a virtual destructor
to Base, and to use reinterpret_cast. That way, he would have
gotten the exception or the error he seems to want.

OK, you lost me.

No problem. Pete said that you needed a virtual destructor if and only
if the design called for deletion of derived types through a pointer to
base types. Given that the original poster was downcasting, and that he
wanted an error, he probably wanted to use dynamic_cast. Which only
works if there is at least one virtual function. In the absense of any
other virtual function, a virtual destructor is as good a choice as
any. Another possible reason for a virtual destructor.

Quote:
The OP's problem was that he used a C-style cast, which blindly does
precisely what you tell it. I would have thought that dynamic_cast
would have been the correct solution (presuming any virtual functions
at all -- usually required to achieve polymorphism).

Exactly. And as there weren't any other virtual functions in the
example:-).

Quote:
Here's my touchstone for C++-style casts:

static_cast - invoke defined conversion
const_cast - add/remove constness
dynamic_cast - typesafe down-cast
reinterpret_cast - DWIM (do what i mean): interpret the bits of the argument
as if they were the template type

Of the four, I think reinterpret_cast is the hardest to get right. But
I didn't think you would get any type-safety from it. Is it possible
your recommendation is a typo?

Ooops. Very much so. I meant dynamic_cast, of course. (The others
wouldn't require any virtual functions. In a very real sense, they are
all "do as I say, and stop asking questions" types of operators.)

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Wed Feb 25, 2004 2:39 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

In message <8a018872.0402240653.15835ae4 (AT) posting (DOT) google.com>, stelios
xanthakis <mayall (AT) freemail (DOT) gr> writes
Quote:
BTW, to contribute to the discussion, I think a virtual
destructor is also needed in this case:

class A { int x; };
class B { int y; };
class C : A, B { int z; };

int f ()
{
B *b = new C;
delete b;
}

Despite the fact that the classes have no dtors, a virtual dtor
must be present because the above crashes. How does the std
describes this? I don't know...

No, if it there were virtual dtors there would not be a problem
(actually I am surprised that the above code does anything worse than
leak memory). Of course there are dtors because currently there is no
way to avoid every class object having a dtor (well you might declare
one and then not define it but then the linker would complain).


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Wed Feb 25, 2004 3:04 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:

No problem. Pete said that you needed a virtual destructor if and only
if the design called for deletion of derived types through a pointer to
base types.

No, I said that IN THE CONTEXT TO WHICH I WAS REPLYING, the true rule
was that you need a virtual destructor only if your class design calls
for deleting objects of derived types through pointers to the base type.
That was in contrast to the assertion that "[t]o be absolutely precise,
if there is any chance that you will try to delete a dynamic instance
through a base-class pointer [you should have a virtual destructor]."
The point was that decisions about virtual destructors should be based
on concrete design criteria, not on general principles and not on
guesses.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Tutone
Guest





PostPosted: Wed Feb 25, 2004 3:05 pm    Post subject: Re: typecasting the base class to derived class. Reply with quote

"stelios xanthakis" <mayall (AT) freemail (DOT) gr> wrote:

[snip]

Quote:
BTW, to contribute to the discussion, I think a
virtual
destructor is also needed in this case:

class A { int x; };
class B { int y; };
class C : A, B { int z; };

OK, C inherits privately from A & B.

Quote:
int f ()
{
B *b = new C;

That shouldn't even compile - B is a private base
class of C.

Quote:
delete b;
}

Despite the fact that the classes have no dtors,

Sure they do - well they would but for the fact that
your code doesn't compile - they would have the
compiler-generated default destructor. I think you
mean they have no user-defined destructors, but so
what?

Quote:
a virtual dtor
must be present because the above crashes. How does
the std
describes this? I don't know...

OK, your example includes both private inheritance and
multiple inheritance, both of which are red herrings
that distract from the issue. Let me simplify your
example:

class Base {};

class Derived : public Base { int i; };

int main()
{
Base* b(new Derived);
delete b;
}

That's undefined behavior, because Base doesn't have a
virtual destructor (although it does have a
nonvirtual, compiler-generated destructor). Since
it's undefined, "crashes" falls within the type of
behavior the program could exhibit.

Best regards,

Tom
















__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.