12
#include <stdio.h>
void pass(void* );
int main()
{
    int x;
    x = 10;
    pass((void*)x);
    return 0;
}
void pass(void* x)
{
   int y = (int)x;
   printf("%d\n", y);
}


output: 10

my questions from the above code..

  1. what happens when we typecast normal variable to void* or any pointer variable?

  2. We have to pass address of the variable to the function because in function definition argument is pointer variable. But this code pass the normal variable ..

This format is followed in linux pthread programming... I am an entry level C programmer. I am compiling this program in linux gcc compiler..

Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
  • 4
    "what happen when typcating normal variable to void* or any pointer variable?" Implementation-dependent. Note that it's not guaranteed that casting an `int` to `void*` and back yields the original value (though usually, it does). – Daniel Fischer Apr 15 '13 at 13:51
  • What are you actually trying to achieve? – David Heffernan Apr 15 '13 at 13:55
  • Generally this kind of type casting does not lead to any concern as long as the addresses are encoded using the same length as the "variable type" (`int` in your case). But @DanielFischer is right the risk is that you would lose some information if the storage capacity of your variable is less than the address length. Thus, something like `void *ptr1 = a_pointer(); char ptr_c = (char)ptr1; void *ptr2 = (void*)ptr_c;` would lead to the assertion `ptr1 != ptr2` – Rerito Apr 15 '13 at 14:00

3 Answers3

12

I'm only guessing here, but I think what you are supposed to do is actually pass the address of the variable to the function. You use the address-of operator & to do that

int x = 10;
void *pointer = &x;

And in the function you get the value of the pointer by using the dereference operator *:

int y = *((int *) pointer);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    "I think what you should do is actually pass the address of the variable to the function" Not necessarily. If this is the data to a thread procedure, then you quite commonly want to pass by value. – David Heffernan Apr 15 '13 at 13:56
  • @DavidHeffernan I rephrased that sentence a little. – Some programmer dude Apr 15 '13 at 13:57
  • 1
    If you are going to pass the address you typically need to exert some more control over the lifetime of the object. Usually that means the pointer is allocated with `malloc` and then destroyed by calling `free` in the thread proc. Automatic storage isn't what you need for thread proc. I know the code in Q is not for thread proc, but it's clearly mentioned as the motivation. – David Heffernan Apr 15 '13 at 14:00
  • @DavidHeffernan, sane thread APIs wouldn't send integral data to the thread procedures, they would send pointers. Even though what you say regarding the lifetime of the object is true, integral types are too limited for a generic API. – Shahbaz Apr 15 '13 at 14:00
  • And in this context, it is very very very common to see programmers lazily type cast the `void *` to something like `int`. Anyway, if the OP wants a paranoid scheme, he can still malloc the appropriate amount of data to pass its value using a pointer ! – Rerito Apr 15 '13 at 14:03
  • This also works: `int x = 10; void *pointer = &(int){ x };` – Kaiepi Nov 05 '18 at 21:06
  • This answer does not address the original question though – Mikhail2048 Feb 19 '23 at 11:54
0

Please read why glib provide macros for this kind of conversions, there's no need to repeat the text here. The main point is: a pointer has a platform dependent size.

Tarantula
  • 19,031
  • 12
  • 54
  • 71
  • 5
    On the contrary, there _is_ a need to repeat the text here. That link will sooner or later rot, turning your answer to a completely useless one. See [here](http://meta.stackexchange.com/q/118582/169090) for more information. – Shahbaz Apr 15 '13 at 14:10
0

If you are planning to use pthreads and you are planning to pass the pass function to pthread_create, you have to malloc/free the arguments you are planning to use (even if the threaded function just need a single int).

Using an integer address (like &x) is probably wrong, indeed each modification you will execute on x will affect the pass behaviour.

Giacomo Tesio
  • 7,144
  • 3
  • 31
  • 48
  • You don't necessarily _have_ to. You could also keep the parameters global, or even on the stack, if it's the same function who calls `pthread_create` and `pthread_join` which is quite often the case (`main` creates threads and then joins them before exit). – Shahbaz Apr 15 '13 at 14:31
  • @Shahbaz you could... but I will not suggest to a C newbie to use globals. As for the stack, I've written a few libraries using pthreds, thus I don't agree that what you describe "is quite often the case". But, sure, in that specific case you can pass a local variable address, **if you know what you are doing**. – Giacomo Tesio Apr 16 '13 at 09:03