3

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

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
Muhammad Farhan
  • 359
  • 2
  • 4
  • 12
  • Its not a good idea to convert a double* to a double. Why do you want to do it? Anyways you can use the reinterpret_cast for such conversions. – Prasoon Saurav Dec 24 '09 at 05:38
  • Also read this: http://stackoverflow.com/questions/332030/when-should-staticcast-dynamiccast-and-reinterpretcast-be-used – Prasoon Saurav Dec 24 '09 at 05:40
  • 1
    I have copied your comment from the answers into your actual question, and added some formatting. This should allow it to be seen and read more easily. It's generally a good idea to include such a snippet in your original question. – Brian Campbell Dec 24 '09 at 06:21
  • Many thanks for going through the trouble. – Muhammad Farhan Dec 24 '09 at 06:36
  • That pseudocode still isn't very helpful. What is supposed to be on the right-hand side? What does LinkedListCurrent(angles) do? Why are you implementing your own linked list in C++ rather than use std::list? Are you sure you want to be using C at all? – Potatoswatter Dec 24 '09 at 08:36

6 Answers6

8

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
  • 322,767
  • 57
  • 360
  • 340
  • 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*. – Muhammad Farhan Dec 24 '09 at 06:10
  • 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. – Todd Gamblin Dec 24 '09 at 18:05
  • `reinterpret_cast` wants to be used. :( – GManNickG Dec 24 '09 at 18:10
  • @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 Dec 24 '09 at 18:25
2

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
  • 18,602
  • 6
  • 51
  • 60
  • 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? – Muhammad Farhan Dec 24 '09 at 05:46
  • 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 Dec 24 '09 at 05:52
  • if you really mean you want to use the address of `dp` in `e`, then you'll have to explain why. – just somebody Dec 24 '09 at 05:54
  • 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*. – Muhammad Farhan Dec 24 '09 at 06:08
1

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
  • 12,748
  • 25
  • 83
  • 121
0

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
  • 134,909
  • 25
  • 265
  • 421
0

Use reinterpret_cast.

double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
fushar
  • 388
  • 2
  • 12
  • 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 Dec 24 '09 at 07:06
0

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
  • 45,033
  • 10
  • 85
  • 120