problem with Void Pointer

Started by
19 comments, last by Julian90 16 years, 9 months ago
I tried to cast from a float pointer to a void pointer and i failed. void* sum(void* x, void* y) { return ((void*)(*((float *)x) + *(float*)y)); } I got compiler error: error C2440: 'type cast' : cannot convert from 'float' to 'void *'.
Advertisement
For the love of god, why?

Your error is because you cast the void pointers to float pointers, which you dereference and add together. You then try to cast the resulting float to a void pointer (illegally). Take the address of the result and return that.

You still have problems though. For starters, you will be returning the address of a value on the stack, and that's a no-no.

This should compile:
void* sum(void* x, void* y)
{
return (void*)&(*((float *)x) + *((float*)y));
}

But don't do that. Just pass in floats, and return a float.
i got compiler error again:
error C2102: '&' requires l-value.
but i dont understand why does it work:
return ((void*)(*(int*)x + *(int*)y));
it works well
Oops, you'd probably have to store the result of the addition in a temp variable and take the address of that, instead of what I did.

But here, this will work even better:
float sum(float x, float y)
{
return x + y; //wasn't that quick and painless?
}

edit:
Quote:Original post by Watchman234
but i dont understand why does it work:
return ((void*)(*(int*)x + *(int*)y));
it works well


No, it doesn't. It certainly doesn't do what you think it does. There you add together x and y as ints, resulting in an int. You then cast the result to a void pointer, which unfortunately works, because an address can be represented as an integer. The pointer will, of course, point at complete garbage, because you're treating the result of an arbitrary addition as a valid location in memory.

In short, don't use void pointers. Ever.
but this is not my purpose , my purpose is:
typedef enum { SIZE_OF_INT , SIZE_OF_LONG, SIZE_OF_FLOAT, SIZE_OF_CHAR } SIZE;

void* sum(void* x, void* y, SIZE size)
{
switch(size)
{
case SIZE_OF_INT:
return ((void*)(*(int*)x + *(int*)y));
case SIZE_OF_FLOAT:
return ((void*)(*((float *)x) + *(float*)y));
case SIZE_OF_LONG:
return ((void*)(*(long*)x + *(long*)y));
case SIZE_OF_CHAR:
return ((void*)(*(char*)x + *(char*)y));

}
return NULL;
}
The compiler say you can't convert a float to a pointer to a void. First you convert two void pointers to floats ( the *((float *)x) and *(float*)y) does this) and then you add them together, resulting in a float. Then you try and convert your float with the (void *) which isn't allowed (this is what the compiler complains about).
I would avoid something like this, really, since I don't see the point of it at all. You can't send anything but floats to this function and get a useful result anyway so it seems strange.
Something that might fix it would be to throw in an & to convert the resulting float to a float pointer which would be converted to a void pointer. I do suspect that it might lead to some unexpected behavior though with the function creating a temporary variable which then falls out of scope when the function returns, which leaves your returned void pointer pointing to something it shouldn't.

Can't test it at the moment but here's what I mean:
void* sum(void* x, void* y){return ((void*) &(*((float *)x) + *(float*)y));}


Edit: Beaten to it by miles, I see ;)

However, with your added post, I do realize that the size of float ant int are the same on many modern system ? You would be far better off to make a template.


use templates?
Quote:Original post by Watchman234
but this is not my purpose , my purpose is:
typedef enum { SIZE_OF_INT , SIZE_OF_LONG, SIZE_OF_FLOAT, SIZE_OF_CHAR } SIZE;

void* sum(void* x, void* y, SIZE size)
{
switch(size)
{
case SIZE_OF_INT:
return ((void*)(*(int*)x + *(int*)y));
case SIZE_OF_FLOAT:
return ((void*)(*((float *)x) + *(float*)y));
case SIZE_OF_LONG:
return ((void*)(*(long*)x + *(long*)y));
case SIZE_OF_CHAR:
return ((void*)(*(char*)x + *(char*)y));

}
return NULL;
}


Welcome to the wonderful world of C++:
template <class T>T sum( T x, T y ){    return x + y;}
but i use C and not C++
ints and floats are the same size: 4 bytes

what you are trying to do is the worst thing imaginable. I don't think a situation exists in which this is the correct solution.

-me

This topic is closed to new replies.

Advertisement