aj3u@jade.cs.virginia.edu (Asim Jalis) (05/28/91)
I want to write a function that takes as arguments pointers to pointers to any type. As in, func(void **p) { ... } main() { int *i; float *f; char *c; func(&i); func(&f); func(&c); } However, the compiler gives me warnings about incompatible type for all the function calls. The code itself works fine, but I was wondering if somehow I could also get rid of the warnings, perhaps by doing this in a more elegant way. Basically what I want is a type that would coerce to a pointer to a pointer to a type, for any type. Sort of one level beyond simple "void *". Any help would be appreciated. Asim Jalis.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/28/91)
Yes, void ** is valid, and it means pointer-to-generic pointer. Note that void ** itself may be represented some other way entirely; void ** is not itself a generic pointer. In article <AJ3U.91May27213633@jade.cs.virginia.edu>, aj3u@jade.cs.virginia.edu (Asim Jalis) writes: > func(void **p) > { ... } > > main() > { int *i; float *f; char *c; > > func(&i); func(&f); func(&c); > } > > However, the compiler gives me warnings about incompatible type for > all the function calls. The compiler is RIGHT. You promised it (oh, you deceiver) that you would give func() pointers to generic (void*) pointers (call the representation of generic pointers REPRESENTATION 0) But you lied (oh, you scoundrel, you). You gave it -- a pointer to (a pointer to int -- REPRESENTATION 1) -- a pointer to (a pointer to float -- REPRESENTATION 2) -- a pointer to (a pointer to char -- REPRESENTATION 0) char* and void* use the same representation. But void*, int*, and float* need not even be the same _size_, let alone use the same physical representation. > The code itself works fine, no, there is a bug in there, waiting, like a blood-sucking insect poised on a bush waiting for a deer to pass by, for an opportunity to bite. > Basically what I want is a type that would coerce to a pointer to a > pointer to a type, for any type. Sort of one level beyond simple > "void *". Why do you want to do _that_? If you _could_ do it, you would be throwing away information that the receiver would need in order to be able to _use_ the thing? What's the context? -- Should you ever intend to dull the wits of a young man and to incapacitate his brains for any kind of thought whatever, then you cannot do better than give him Hegel to read. -- Schopenhauer.
hp@vmars.tuwien.ac.at (Peter Holzer) (05/28/91)
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: [...good explanation why void ** isn't a pointer to any pointer deleted...] >> Basically what I want is a type that would coerce to a pointer to a >> pointer to a type, for any type. Sort of one level beyond simple >> "void *". >Why do you want to do _that_? If you _could_ do it, you would be >throwing away information that the receiver would need in order to >be able to _use_ the thing? What's the context? I don't know what the original poster wanted to do, but since I was in the same situation once, I can give you an example why anybody would like to do something like that. In MARS (a real-time system developed at our department) exists a system-call which is now defined as: int receivem (msg_name name, void * msg, unsigned short flags); Messages are (in C) defined as structures and there are several types. For some reason, which is not relevant here, msg is not a pointer to the structure, but a pointer to a pointer to structure. Of course one common error is to define a struct foo * mymsg and then pass mymsg instead of &mymsg. With the current prototype this error is not detected by the compiler, but if some type `pointer to any pointer' existed, this type of error could be catched. Unfortunately this is not possible in C. #pragma speculation_mode on /* :-) */ There is a rumor among C-programmers that `all struct-pointers smell the same.' (I could not find any assertion of this in the standard, and I can find pro's and con's for such a rule, so I call it a rumor, undoubtedly someone who knows will tell me if it is correct or not). If this rumor is true, a pointer to pointer to any struct would be legal (At least there is no reason why it should not be legal). So we could declare the systemcall above as: int receivem (msg_name name, struct ** msg, unsigned short flags); which is almost exactly what the designer of the system call had in mind. -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
gwyn@smoke.brl.mil (Doug Gwyn) (05/29/91)
By the way, there is no need to go through a lot of gyrations to attain the originally-stated goal. Just declare the parameter as a void * anyway, and apply the appropriate cast inside the function where it is used. E.g. void foo(void *param) { ++(*(struct msg **)param)->field; } After all, the thing pointed to, in this case a "struct msg *", is also an object and so a pointer to it (a "struct msg **") can be fairly conveniently converted to void* and back.
wittig@gmdzi.gmd.de (Georg Wittig) (05/29/91)
hp@vmars.tuwien.ac.at (Peter Holzer) writes: >[...good explanation why void ** isn't a pointer to any pointer >>Why do you want to do _that_? >For some reason, which is not relevant here, msg is not a pointer to >the structure, but a pointer to a pointer to structure. Of course one >common error is to define a struct foo * mymsg and then pass mymsg >instead of &mymsg. With the current prototype this error is not >detected by the compiler, but if some type `pointer to any pointer' >existed, this type of error could be catched. Unfortunately this is not >possible in C. Why not use unions? Example: typedef union { struct struct1 *p_struct1; struct struct2 *p_struct2; ... } my_union_t; and pass the union address to your function: myfunc (&myunion); ... myfunc (my_union_t *p_union){ ... p_union -> p_struct2 -> ... This has the advantage that you MUST define which structures are allowed in that context, and the compiler can check consistency. ... And you don't need void **. -- Georg Wittig GMD-Z1.IT P.O.Box 1240 | "Freedom's just another word D-W-5205 St. Augustin 1 (Germany) | for nothing left to lose" email: wittig@gmdzi.gmd.de | (from "Me and Bobby McGee", telephone: (+49) 2241 14-2294 | Janis Joplin, Kris Kristofferson)