Re: manipulating void* in array
- From: "S.Tobias" <siXtY@xxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: 16 Jul 2005 21:03:16 GMT
Stijn van Dongen <svd@xxxxxxxxxxxx> wrote:
Your description is very vague, you'd better post some pseudo-code
to illustrate your problem (but please, as little as necessary).
I'll do my best.
> A question about void*. I have a hash library where the hash create
> function accepts functions
> unsigned (*hash)(const void *a)
> int (*cmp) (const void *a, const void *b)
>
> The insert function accepts a void* key argument, and uses the
> functions above to store this argument. It returns something (linked to
> the key) that the caller can store a value in.
You mean the caller first inserts a key, and then fills in the rest
of the data? It doesn't sound like a good interface. Better compute
everything before inserting; insert function needn't return anything.
>The actual key argument
> is always of the same pointer type (as seen in the caller, say foo*).
If you operate on one data type (foo), then there's no advantage in
having void* pointers; use foo* in `hash' and `cmp' (I've noticed
they don't take size argument, therefore they must know the type,
or at least the size, of data they work on), and others. Use void* when
you need generic pointer, when the data you work on is unknown.
>
> Now I would like to have a function, say hash_keys, which returns all
> keys in the hash as a pointer to a malloced array of void*.
As above, you could return an array of `foo*'.
>However,
> there is not really a type I can use.
Why?
>I see two possible solutions.
> The first is to typedef a struct containing a void pointer:
>
> typedef struct {
> void* pp;
> } genpp;
>
> and have hash_keys return genpp* (the size could be written in an int*
> argument
> to hash_keys). This would make accessing the keys cumbersome.
There's no point in returning a struct having only one member. Return
the member.
Some propositions:
/* return array of void* (actually, pointer to its first element)
and it's size in `*size' */
void* hash_keys(size_t *size);
/* return array of void* in `keys' argument, and its size in
the return value; basically same as above, but the meaning
of arguement and return value is reversed */
size_t hash_keys(void* *keys);
/* return array of void*, N+1 elements, the last is null ptr */
void* hash_keys(void);
/* return array and its size as a pair in a struct */
struct { void* a; size_t s; } hash_keys(void);
>
> Solution 2) is illegal C (I think), but it's tempting. hash_keys would
> construct an array of void*-sized elements and copy its key pointers
> there using char* arithmetic.
There's no reason for that, you should just assign one type to another,
an automatic conversion will be performed (no need for casting).
void *pv;
foo *pf;
pv = pf; //okay
pf = pv; //okay
>It would return void* and the caller
> would cast it to foo**.
I don't quite get what you think here, but I think you think wrong.
>For one thing, this assumes sizeof(void*) is
> sizeof(foo*) for all possible foo.
You can never assume that (unless `foo' is `char', which is probably
not what you have).
>For another, I see nothing in the
> standard on void* that would support any of this. However, it feels as
> if approach 2) is conceptually extremely similar to the first and I
> suspect it would work on nearly all platforms/compilers.
I don't see much difference between them. They differ in how
the values are stored in the array.
I don't quite understand what your problem is: is it how to return
an array to the caller, or how to store values in it? You need
to post some code to explain it.
>
> The questions then are,
>
> 1. Did I miss another solution where hash_keys creates some array?
> 2. Is my assessment of 2) correct?
I think solution 2 had unnecessary flaws. You need to explain more
what your real problem is.
> 3. On what kind of platforms/compilers would 2) fail? Outside the scope
> of this newsgroup, I know, but perhaps some kind soul can comment.
If the code is written in a portable manner, then it will fail only
on a broken implementation. If it isn't, It may fail on the same
platform of yours tomorrow, and always on your customers' machines
while you're not watching.
--
Stan Tobias
mailx `echo siXtY@xxxxxxxxxxxxxxxxxxxxxxxxxx | sed s/[[:upper:]]//g`
.
- References:
- manipulating void* in array
- From: Stijn van Dongen
- manipulating void* in array
- Prev by Date: Re: Is there any ANSI method to extract/tokenize argv[ ]
- Next by Date: Re: how to do ?
- Previous by thread: manipulating void* in array
- Next by thread: Re: manipulating void* in array
- Index(es):
Relevant Pages
|
|