Casting and Unsafety
Can someone explain me why, for example, casting to and from void * may me unsafe? I canīt figure it out. What other casts are considedred unsafe? If someone can give some examples I will apreciate! Thanks.
The problem is that void* doesn't contain any type information besides the fact that you're dealing with a pointer. So you can easily lose essential type information by accidentally casting to the wring type. For example:
string * ps;
void * p=ps;//lose type information of string
Person * per=(Person*) p; //very bad, but will compile
char * buff (char*) p; //same here
double * pd= (double*) p;// horrible
Generally speaking, explicit casts are never a grat idea; not always can you avoid them (especially in low-level code) but they are always dangerous, pretty non-portable and violate basic OO principles. void * is particularly dangerous because it enables you to cast anything to anything disabling the compiler's sanity checks.
Last edited by Danny; 04-05-2005 at 12:52 PM.
what do you mean when you say non-portable? Can you give an example?
void *p = &l;
int * pi=(int*)p;
This code will work in 32-bit system where long and int occupy the same size. In other cases, there will be a truncation or chopping of bytes. If for example int occupies 16 bits and long 32, then the last 16 bits of the long are lost. You can't tell whether this code will work as expected without knowing on which platform it's compiled. So, that's one example of nonportable conversions.
And of course, there's the issue of converting a pointer to a function (i.e., a freestanding function) to void * and vice versa. On some systems, this will work; on others it won't. The standard doesn't guarantee that this is safe so you're doing it at your own risk...
Finally, there's the issue of multiple inheritance and crosscasts. It's too complicated to be demonstrated concisely but the bottom line is that you can't used void * to store the address of a virtual base class subobject or the address of a secondary base in a myultiply-inherited class.
Last edited by Danny; 04-05-2005 at 06:10 PM.
Danny, 3 questions are wandering in my mind:
So portability is related to wether the objects (when moving between platforms) will have the enough space in memory (to preserve their original structure and values ) when being casted? Is this ok?
Are there alignment issues involved as well?
You īve just mentioned multiple inheritance...where I can find a deep essay about this topic?
no, it is not sufficient to provide extra memory, because:
yes, there are 'padding' and alignment problems, and unsafe casts may put things in the wrong space (even if no memory is violated, you can still be moved a byte left or right and get hosed up by that).
it's not just a matter of occupying the same space. There are alignment issues as you stated, there's also the byte ordering problem that jonnin mentioned and there's the padding bytes that each compiler inserts between members to ensure that each member starts on a properly aligned address.
As for multiple inheritance, there is a very enlightening example shown in this Safari online sample chapter:
I couldn't copy and past it here because of copyright issues but you can register for free and read it (registration is free for the first 14 days, which is plenty of time to read this short chapter...)
Last edited by Danny; 04-06-2005 at 08:50 PM.
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center