Sign in to follow this  

Curiosity about type-casting ...

This topic is 4281 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
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
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
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
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

This topic is 4281 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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