tags:

views:

275

answers:

6

Any ideas for this typecasting problem?

Here's what I am trying to do. This is not the actual code:

LinkedList* angles;
double dblangle; 
dblangle = (some function for angle calculation returning double value);
(double*)LinkedListCurrent(angles) = &double;

I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.

+2  A: 

why on earth would you want to use a memory address as a floating point number?

if you meant dereference:

double d = 1.0;  // create a double variable with value 1.0
double *dp = &d; // store its address in a pointer
double e = *dp;  // copy the value pointed at to another variable
just somebody
I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?
Farhan
I don't understand. the code does both: stores an address in a pointer, then dereferences the pointer to get the number pointed at. I'll add comments.
just somebody
if you really mean you want to use the address of `dp` in `e`, then you'll have to explain why.
just somebody
Here's what I am trying to do. This is not the actual code:LinkedList* angles;double dblangle;dblangle = (some function for angle calculation returning double value);(double*)LinkedListCurrent(angles) = I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
Farhan
+6  A: 

You use the unary * operator to dereference a pointer. Dereferencing a pointer means extracting the value pointed to, to get a value of the original type.

// Create a double value
double foo = 1.0;
// Create a pointer to that value
double *bar = &foo;
// Extract the value from that pointer
double baz = *bar;

edit 2: (deleted edit 1 as it was not relevant to your actual question, but was based on a miscommunication)

From your clarification, it looks like you are wondering how to set a value pointed to by a pointer that has been cast from a void * to a double *. In order to do this, we need to use the unary * on the left hand side of the assignment, in order to indicate that we want to write to the location pointed to by the pointer.

// Get a void * pointing to our double value.
void *vp = &foo;
// Now, set foo by manipulating vp. We need to cast it to a double *, and
// then dereference it using the * operator.
*(double *)vp = 2.0;
// And get the value. Again, we need to cast it, and dereference it.
printf("%F\n", *(double *)vp);

So, I'm assuming that your LinkedListCurrent is returning a void * pointing to some element in the linked list that you would like to update. In that case, you would need to do the following:

*(double*)LinkedListCurrent(angles) = dbangle;

This updated the value pointed to by the pointer returned from LinkedListCurrent to be equal to dbangle. I believe that is what you are trying to do.

If you are trying to update the pointer returned by LinkedListCurrent, you can't do that. The pointer has been copied into a temporary location for returning from the function. If you need to return a pointer that you can update, you would have to return a pointer to a pointer, and update the inner one.

My explanation above is based on what I believe you are trying to do, based on the example snippet you posted and some guesses I've made about the interface. If you want a better explanation, or if one of my assumptions was bad, you might want to try posting some actual code, any error messages you are getting, and a more detailed explanation of what you are trying to do. Showing the interface to the linked list data type would help to provide some context for what your question is about.

edit 3: As pointed out in the comments, you probably shouldn't be casting here anyhow; casts should be used as little as possible. You generally should use templated collection types, so your compiler can actually do typechecking for you. If you need to store heterogenous types in the same structure, they should generally share a superclass and have virtual methods to perform operations on them, and use dynamic_cast if you really need to cast a value to a particular type (as dynamic_cast can check at runtime that the type is correct).

Brian Campbell
Here's what I am trying to do. This is not the actual code: LinkedList* angles; double dblangle; dblangle = (some function for angle calculation returning double value); (double*)LinkedListCurrent(angles) = I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
Farhan
Yay, the sole correct answer! +1
Pavel Minaev
It's nice that people not only answer questions but actually ask more questions to figure out what the real problem was. I deleted my answer so this will get voted up, since this is much more comprehensive. +1.
tgamblin
`reinterpret_cast` wants to be used. :(
GMan
@GMan Really, there shouldn't need to be any sort of cast used. You shouldn't use a linked list data type with void pointers in C++, but should instead use either a `templated` data structure, or a data structure containing pointers to objects with virtual functions. At worst you should be using dynamic_cast if you need to extract objects of a particular type. It's hard to explain all of that in one answer, especially without some more information on what he's trying to do, so I figured I would try and answer just the immediate question and not go further into issues of style.
Brian Campbell
A: 

Use a union. If you want the store two variables in one memory location (but not at the same time), you don't have to pretend that one is the other.

union double_and_ptr {
    double d;
    double *p;
};

double_and_ptr x, y;
x.d = 0.1;
y.p = &x.d; // store a pointer in the same place as a double
y.d = x.d * 1.2; // store a double in the same place as a ptr
Potatoswatter
A: 

Use reinterpret_cast.

double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
fushar
Technically correct. But I cannot imagine why someone would do this ... if they really understood what it did. (Besides, doesn't it only "work" if pointers are 64 bits?)
Stephen C
A: 

In answer to this:

I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?

You would do something like this:

// declare a pointer to a double
double *pointer_to_double; 

// declare a double
double my_double = 0.0;

// use the indirection operator (*) to dereference the pointer and get the value
// that it's pointing to. 
my_double = *pointer_to_double;

This might be done like so in a real program:

void print_chance_of_snow(double *chance)
{
    double d = *chance;
    d = d * 100; // convert to a percentage
    printf("Chance of snow is: %.2f%%\n", d);
}

int main(int argc, char *argv[])
{
    double chance_of_snow = 0.45;
    print_chance_of_snow(&chance_of_snow); 
}
Seth
+1  A: 

Note this line:

(double*)LinkedListCurrent(angles) = &double;

where you've written &double, it i think should be &dbangle. To improve readability, I would write:

((double*)LinkedListCurrent(angles)) = &dbangle;

However, you should not do this type of conversion as others mentioned.

Donotalo