7

I'm writing an interpreter and I'd like to be able to store whatever value a function returns into a void pointer. I've had no problem storing ints and various pointers as void pointers but I get an error when trying to cast a double as a void pointer. I understand that doubles are stored differently than integers and pointers at the bit level, but I don't understand why I can't place whatever bits I want into the pointer (assuming it has enough memory allocated) and then take them out later, casting them as a double.

Is it possible to cast a double to a void pointer using syntax I'm not aware of or am I misunderstanding how void pointers work?

Jack
  • 73
  • 1
  • 3

4 Answers4

16

On many systems a double is 8 bytes wide and a pointer is 4 bytes wide. The former, therefore, would not fit into the latter.

You would appear to be abusing void*. Your solution is going to involve allocating storage space at least as big as the largest type you need to store in some variant-like structure, e.g. a union.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    I can't believe I've never heard of a union before. This is exactly what I was looking for. – Jack Jul 04 '11 at 19:41
3

Of course it's possible to cast it. Void pointers is what makes polymorphism possible in C. You need to know ahead of time what you're passing to your function.

void *p_v ;
double *p_d ;
p_d = malloc( sizeof( double ) ) ;
p_v = ( void * ) p_d ;
James
  • 31
  • 1
  • 2
    Your example appears to work because `p_d` is a pointer. The op was asking about a non-pointer to void* conversion. –  Mar 03 '16 at 20:06
-1

continue with Fabio. and make sure you are running on x64

int main()
{
    double d = 1.00e+00; // 0x3ff0000000000000
    double* pd = &d;
    void** p = (void**)pd;
    void* dp = *p;
    printf("%f %p %p %p \n", d, pd, p, dp);

    printf("%d %f\n", dp, *(double*)p);

    printf("%f\n", *(double*)(void **)&d);
}

output

1.000000 0000000353F1FA30 0000000353F1FA30 3FF0000000000000
0 1.000000
1.000000
cpuwolf
  • 27
  • 3
-3

Here is it

int main ( ) {
    double d = 1.00e+00 ; // 0x3ff0000000000000
    double * pd = & d ;
    void * * p = ( void * * ) pd ;
    void * dp = * p ;
    printf ( "%f %p %p %p \n" , d , pd , p , dp ) ;
    return 0 ;
} ;

output

1.000000 0x7fff89a7de80 0x7fff89a7de80 0x3ff0000000000000

2nd and 3rd addresses could be different. A shortcut

void * dp = * ( void * * ) & d ;

Cheers

Fabio
  • 211
  • 1
  • 8
  • This is undefined behaviour (strict aliasing violation) – M.M Oct 05 '17 at 04:21
  • @M.M it is not. I'm casting the pointer, I know what I'm doing, it's not c++, it compiles and gives the right output. I would not suggest to use a such technique in a long code, but I'm right. – Fabio Oct 05 '17 at 12:09
  • The expression `*p` has type `void *` but is accessing memory that is actually of type `double *` . Those could even be different sizes – M.M Oct 05 '17 at 20:44
  • you're right, I assumed that everything was 64 bit aligned... otherwise you need iterate a read with pchar of a given length – Fabio Oct 06 '17 at 10:39
  • 1
    `* ( void * * ) & d` is undefined behavior, and it does violate strict aliasing. – S.S. Anne Sep 12 '19 at 20:19