assigning void * w/o cast

  • Thread starter trying_to_learn
  • Start date
T

trying_to_learn

Hello All
Have another qn from the practice exercises. I ve done the exercise and
the birds fly member fn was called successfully. But i still cant answer
the authors qn. why this ability to assign void * has had to be avoided
in C++. I didnt even instantiate bird obj then how was i able to call a
bird member fn. Im confused.

Quote: "Qn)Create a class called bird that can fly( ) and a class rock
that can’t. Create a rock object, take its address, and
assign that to a void*. Now take the void*, assign it to a
bird* (you’ll have to use a cast), and call fly( ) through
that pointer. Is it clear why C’s permission to openly
assign via a void* (without a cast) is a “hole” in the
language, which couldn’t be propagated into C++?" End Quote.

class bird
{
public:
void fly(void);
};
void bird::fly(void) {cout<<"Birds Fly"<<endl;}
class rock{};

//!!!!!!!!!!MAIN!!!!!!!!
void main(void)
{rock rockObj;
void * voidptr=&rockObj;
bird* birdptr=(bird*)voidptr;
//!bird* birdptr=voidptr;//illegal
birdptr->fly();
}
 
C

Cy Edmunds

trying_to_learn said:
Hello All
Have another qn from the practice exercises. I ve done the exercise and
the birds fly member fn was called successfully. But i still cant answer
the authors qn. why this ability to assign void * has had to be avoided in
C++. I didnt even instantiate bird obj then how was i able to call a bird
member fn. Im confused.

Quote: "Qn)Create a class called bird that can fly( ) and a class rock
that can’t. Create a rock object, take its address, and
assign that to a void*. Now take the void*, assign it to a
bird* (you’ll have to use a cast), and call fly( ) through
that pointer. Is it clear why C’s permission to openly
assign via a void* (without a cast) is a “hole” in the
language, which couldn’t be propagated into C++?" End Quote.

class bird
{
public:
void fly(void);
};
void bird::fly(void) {cout<<"Birds Fly"<<endl;}
class rock{};

//!!!!!!!!!!MAIN!!!!!!!!
void main(void)

// should be int main()
{rock rockObj;
void * voidptr=&rockObj;
bird* birdptr=(bird*)voidptr;
//!bird* birdptr=voidptr;//illegal
birdptr->fly();
}

You just made a rock fly. Congratulations!

This worked because class bird doesn't have any associated data used in
bird::fly(). What this points out is that methods of C++ functions aren't
really "in the object". There is only one method which serves all objects of
that type. In other words, in C it is like this:

struct bird_data {};
void bird_fly(bird_data*) {cout<<"Birds Fly"<<endl;}

Although you don't see any argument in bird::fly, there is a hidden one
called "this" which points to the associated data. Since bird::fly doesn't
use its "this" pointer (just as bird_fly doesn't use bird_data) the function
worked. (It's still undefined behavior though, so kids, don't try this at
home.)

Your instructor is quite right to call void pointers a hole in the C++ type
system. That's what they are supposed to be, but if you use them you make
make rocks fly by accident. So don't use void pointers unless you need them
for legacy code or very low level operating system operations.
 
D

David White

trying_to_learn said:
Hello All
Have another qn from the practice exercises. I ve done the exercise and
the birds fly member fn was called successfully. But i still cant answer
the authors qn. why this ability to assign void * has had to be avoided
in C++. I didnt even instantiate bird obj then how was i able to call a
bird member fn. Im confused.

It was just an accident of the way you created the classes that the call
worked. You didn't do anything in the function that depended on any
properties of the object or its class.
Quote: "Qn)Create a class called bird that can fly( ) and a class rock
that can’t. Create a rock object, take its address, and
assign that to a void*. Now take the void*, assign it to a
bird* (you’ll have to use a cast), and call fly( ) through
that pointer. Is it clear why C’s permission to openly
assign via a void* (without a cast) is a “hole” in the
language, which couldn’t be propagated into C++?" End Quote.

The reason is that it shouldn't be possible to make the rock fly without the
compiler giving an error or your forcing the rock to attempt to fly (by
using a cast). If you didn't need the cast you could accidentally (or
deliberately) do things that are wrong or dangerous without the compiler
giving an error.

DW
 
M

Mike Wahler

Cy Edmunds said:
Your instructor is quite right to call void pointers a hole in the C++ type
system. That's what they are supposed to be, but if you use them you make
make rocks fly by accident. So don't use void pointers unless you need them
for legacy code or very low level operating system operations.

So maybe we should codify the advice about void pointers as:
"Don't throw rocks (they can break your code)."

:)

-Mike
 
D

Duane

Mike Wahler said:
So maybe we should codify the advice about void pointers as:
"Don't throw rocks (they can break your code)."

Actually throwing rocks should be fine, it's throwing birds that could
be problematic.
 
V

Victor Bazarov

Duane said:
Actually throwing rocks should be fine, it's throwing birds that could
be problematic.

Is that because it's easier to catch a rock than a bird?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top