python152
python152

Reputation: 1941

passing value through pointer to void

The snippet passes the value of id to a routine that takes a general void * structure. I am confused as to why it works: why can you cast the long to void* and cast it back with a long.

In particular, I was thinking if you want to pass by pointer, then you should pass the address of the variable such as &id to the test() function.

#include <stdio.h>

void test(void * id) {
    long myid;
    myid = (long) id;
    printf("my id is %ld\n", myid);
}

int main() {
    long id = 5;
    test( (void *)id);
}

Upvotes: 0

Views: 45

Answers (3)

tdao
tdao

Reputation: 17678

I am confused as to why it works: why can you cast the long to void* and cast it back with a long.

long id = 5;
test( (void *)id);

This is actually valid. You basically mean to pass a void pointer to function test, that pointer holds the address of 5.

In void test(void * id), you cast that pointer back to long which is also valid.

Note in your code you never deference the pointer so things work. If you do dereference the pointer id in test, that would usually lead to segfault due to bad memory access.

Upvotes: 1

Hannu
Hannu

Reputation: 12205

It works because pointers are just numbers.

Your test function "thinks" it received a pointer to memory location 5, and you can of course print this address. You wouldn't be able to assign anything to this location, so *myid = 42 would cause a segmentation fault. Casting a number to a pointer is syntactically correct so your compiler won't moan but it doesn't make any sense. Run this code and see how a pointer looks when printed (ignore the warning from your compiler).

#include <stdio.h>

void test(void *id, long *foo) {
    long myid;
    myid = (long) id;
    printf("my id is %ld, %ld\n", myid, foo);
}

int main() {
    long id = 5;
    long foo;
    foo = 42;
    test( (void *)id, &foo);
}

Upvotes: 1

MSalters
MSalters

Reputation: 179779

It works, because (on your system!) the void* pointer itself contains enough bits to hold all bits of a long value. This is not portable.

You're right that you'd normally cast a long* to void* and back. That is portable.

Upvotes: 4

Related Questions