Re: Confused about "void **"





sunglo@xxxxxxxxxxxx wrote:
> My doubt comes from trying to understand how thread return values work
> (I know, it's off topic here), and I'm wondering about the meaning of
> the "void **" parameter that pthread_join expects (I think this is
> topical, since it's a C question, but please correct me and apologies
> if I'm wrong).
>
> I suppose that it's this way to allow for "generic" pointer
> modification, but this implies dereferencing the "void **" pointer to
> get a "void *" one. So, is this allowed or does the implementation have
> to play some trick somewhere, like for example casting the void ** to
> another type (for example, int ** on a 32 bit machine) that can then be
> safely dereferenced?

No tricks. You cannot dereference a `void*' because
it points to what's called an "incomplete type" -- loosely
speaking, it points to the start of a piece of anonymous
memory of unknown size and significance. You know where
the memory is, but you don't know how big it is or how to
interpret its contents -- in short, you don't know how to
"refer" to it.

However, a `void*' itself is a perfectly normal data
object, just like an `int' or a `double*'. Its size is
known and its representation is known, so if you know that
a certain piece of memory holds a `void*' you have enough
information to fetch or store a `void*' value in that memory.
And what kind of a pointer points to a `void*'? A `void**',
of course. There's no trickery about it.

However, this doesn't mean a `void**' is a "generic
pointer to pointer" in the sense that `void*' is frequently
called a "generic pointer." A `void*' can point to any kind
of data object (because it will not be dereferenced), but
a `void**' can only properly point to a `void*' -- it can't
point to an `int*' or a `double*'. (There's a special rule
that allows it to point to a `char*', but that rule exists
only to legitimize pre-Standard code, and is best ignored.)

What this means (we're straying near the frontiers of
topicality here, but your question is a bona-fide C question
even though it involves beyond-C API's) is that

- Your thread function creates a data object containing
its Final Answer (taking care to use an object that
will survive the thread's demise), takes a pointer
to that object and converts it to `void*' (the
conversion is automatic, but it occurs), and returns
that `void*' value.

- The thread_join() function locates the `void*' value
returned by the defunct thread, and wants to put it
somewhere for your inspection. To receive the value,
you create a `void*' variable somewhere and pass a
pointer to it -- a `void**' -- to thread_join(), which
plunks the value in the place you indicate.

- Now you've got the `void*' that the thread returned,
but you can't do much with it because you can't
dereference it. However, you know the type of the
data object that holds the thread's Final Answer, so
you can convert the `void*' to a pointer to that data
type (again, the conversion is automatic), and with
that pointer you can access to the thread's Last Will
and Testament.

Pseudocode outline:

struct final_answer { int this; double that; };
...
void *thread(...) {
struct final_answer *adios = malloc(sizeof *adios);
...
adios->this = 42;
adios->that = 12e34;
return adios;
}
...
void *raw_result;
struct final_answer *result;
thread_join(..., &raw_result);
/* This ^^^^^^^^^^^ is the `void**' */
result = raw_result;
printf ("%d, %g\n", result->this, result->that);

The `raw_result' variable is necessary here; you cannot
just pass `&result' as the thread_join() argument.

--
Eric.Sosman@xxxxxxx

.



Relevant Pages

  • Re: Is this math test too easy?
    ... > communications glitch; one of the more laughable cartoons ... it was loaded into physical memory and, ... > Or one can interpret the character string as one of the values ... A pointer to an integer? ...
    (sci.math)
  • Re: grow list by tail, pointer example recipe -- please comment
    ... manufacturing a pointer with that address. ... the next cons cell. ... believe these lists are in consecutive memory locations. ...
    (comp.lang.lisp)
  • Re: some unanswered questions on C
    ... A pointer variable that's never been given a value. ... you don't know what memory you're modifying. ... >what i want to ask is that when i declare my buffer for fgets as ... "char *buffer" creates a pointer, ...
    (comp.unix.programmer)
  • Re: "Mastering C Pointers"....
    ... all means go ahead and dive right into the C language. ... Memory is a separate unit which just stores bits. ... A pointer at the hardware level _is an integer_. ... since loops make your logic more much ...
    (comp.lang.c)
  • Re: what is the purpose of C++ smart pointer
    ... pointer tracks the data it is referring to and updates itself ... following the changes of the memory it points to. ... How exactly will the smart pointer know that you moved the ... int * x = new int; ...
    (comp.os.linux.development.apps)