Sign in to follow this  
TFS_Waldo

Curiosity about type-casting ...

Recommended Posts

TFS_Waldo    146
Okay. I just had a question out of curiosity. For example, when using the "memcpy" function, it takes parameters like "void*" and "const void*". But if you create a pointer to "char" or "int" or something, and you pass it to "memcpy", it works. But my question is this. Should I do:
int *pInt  = new int[5];
int *pInt2 = new int[5];
// Fill 'pInt' array
// ...

memcpy(pInt2, pInt, sizeof(pInt));

Or this: "memcpy((void*) pInt2, (const void*) pInt, sizeof(pInt));" Does it really matter?

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
void * works as a pointer to anything. I'm not exactly sure about this but I believe that the C and C++ standards will say that pointer types may be automatically converted to void *.

Share this post


Link to post
Share on other sites
Quote:
Original post by TFS_Waldo
Does it really matter?


It shouldn't, since every compiler I know of supports implicit casting to void * - Since that's the real reason why void pointers exist (General memory handling without casting to char pointers).

EDIT: Wow, looks like Colin Jeanne beat me.

Share this post


Link to post
Share on other sites
NotAYakk    876
I avoid explicitly casting as much as possible.

Explicit casts work even when it makes no sense for them to work.

Instead, I tend to use:
template<typename T>
T implicit_cast(T const& t) {return t;}

for most of my non-dynamic_cast casting needs.

(It is useful for converting between C-types (double to int), and when you want to pass a specific parent class to a function.)

The most common exception to implicit cast is:

template<typename V>
template<typename V>
struct void_caster { template<typename T> static void* work(T v) {return v;}};

template<typename Void>
struct do_cast {
template<typename T> static T work(Void v)
{return reinterpret_cast<T>(v);}
};
template<> struct void_caster<void*>: do_cast<void*> {};
template<> struct void_caster<const void*>: do_cast<const void*> {};

// void cast casts FROM a void TO a different type
// failure to pass in a void will result in a compile error
template<typename T, typename V>
T void_cast(V v) {return void_caster<V>::work<T>(v);}

which makes sure I am casting from a const void* or a void* easy, and prevents you from accidenatally using a C-style/reinterprit cast on a non-void*.

Using reinterprit_cast or C-style casting is dangerous. Because it works when you don't want it to, and when it isn't safe.

Share this post


Link to post
Share on other sites
TFS_Waldo    146
Okay, this leads me to another question. I have seen and read about "dynamic_cast", "static_cast", etc. But I never fully understood them. Can someone give me a (somewhat) detailed explanation about what each does and when the best time to use them is?

Share this post


Link to post
Share on other sites
bradbobak    1825
Quote:

int *pInt = new int[5];
int *pInt2 = new int[5];
// Fill 'pInt' array
// ...

memcpy(pInt2, pInt, sizeof(pInt));


wouldn't sizeof(pInt) return the size of an integer pointer?
I think you mean 'sizeof(int) * 5'

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this