"Juggernaut" <ju************@hotmail.com> writes:
I am trying to create a p_thread
pthread_create(&threads[k], &attr, Teste, (void *)var);
where var is a char variable.
But this doesnt't work, I get this message:
test.c:58: warning: cast to pointer from integer of different size.
Right, because you're casting to a pointer type (void*) from an
integer of a different size (char). (Remember that char is an integer
type.)
pthread_create is strictly off-topic here, but the issues you're
running are really language issues.
Suppose you have a function called foo_create declared like this:
int foo_create(foo_t *foo,
something_t *something,
void *(*start_routine)(void *),
void *arg);
(You may notice a resemblance to pthread_create, which I won't discuss
further since it's off-topic.)
The foo_create() function attempts to create a "foo" (whatever that
may be). Part of the process of creating a "foo" involves calling a
user-defined start routine. The third argument to foo_create is a
pointer to this start routine (a function that takes a single void*
argument), and the fourth argument is the void* value to be passed to
the start routine.
Why void*? Because void* is a generic pointer type. Any object
pointer type can be converted to void*, and vice versa; a void*
pointer can point to any object of any type. foo_create() doesn't
have to know what kind of data you want to pass to your start
function; only the function itself has to know. This is similar to
the method used by the standard qsort() function, which takes a
pointer to a comparison function that in turn takes two void*
arguments, pointers to the values being compared.
You can't call your start routine directly; you call foo_create(),
which calls your start routine. So any information you want to pass
to your start routine has to go through a parameter of type void*.
Converting between integer types and pointer types, as you've
attempted to do, is seldom a good idea. If you really want your start
routine to accept a char argument, you can probably get away with
converting the char value to void*, and letting the start routine
convert the void* back to char, but that's ugly. C has little enough
type checking as it is; subverting it is likely to get you into
trouble. (Note that your start routine can't be declared to take a
char argument; for compatibility with the definition of foo_create(),
it has to accept a void* argument.)
The idea of the void* argument isn't to squeeze information *into* the
pointer argument, it's to use it to *point to* the information you
want. If you need your start routine to accept a larger amount of
information, you can wrap it all in a structure and pass a pointer to
the structure. You'd convert the structure pointer to void* so you
can pass it to foo_create(), foo_create would pass the void* to your
start routine, and your start routine would then convert it from void*
to a structure pointer, which can be used to access the members. (The
conversions can be done implicitly; converting between void* and
another object pointer type doesn't require an explicit cast.)
But if you just want to pass a single char value to your start
routine, the cleanest way to do it is to pass a pointer to a char
object. Your start routine can then convert its void* argument to
char* and dereference it to obtain the original char value.
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.