Reputation: 1941
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
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
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
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