On Oct 17, 2007, at 1:08 PM, Ralf S. Engelschall wrote:
> On Wed, Oct 17, 2007, Jeff Johnson wrote:
>
>> I'm in the last stages of establishing a typedef for
>> data returned from headerGetEntry() et al methods.
>>
>> Since the data is typed, a union is being used:
>> union hRET_s {
>> void * ptr;
>> const char ** argv;
>> const char * str;
>> uint_64 * ui64p;
>> uint_32 * ui32p;
>> uint_16 * ui16p;
>> uint_8 * ui8p;
>> int_64 * i64p;
>> int_32 * i32p;
>> int_16 * i16p;
>> int_8 * i8p;
>> };
>> typedef union hRET_s rpmTagData;
>>
>> Since the current API uses "const void *", there is a need to
>> convert the void * to a union pointer at the moment. I'll fight the
>> You changed rpmlib's API!
>> issues after all the work is actually done.
>>
>> Well I'm baffled by how to achieve the cast. Everything I've tried
>> with
>> casts fails to compile.
>>
>> This hackery with an extra level of indirection manages to change
>> the pointer type, but is perhaps overkill:
>>
>> int headerAddEntry(Header h, int_32 tag, rpmTagType type,
>> const void * p, rpmTagCount c)
>> /*@modifies h @*/
>> {
>> rpmTagData *q = (void *)&p;
>> return (h2hv(h)->hdradd) (h, tag, type, *q, c);
>> }
>>
>> So how does one achieve casting from void * to a union?
>>
>> Inquiring minds want to know ...
>
> Why is there "(void *)&p"? I would have expected just "(void *)p" or
> even "(rpmTagData *)p". Also, you are passing "*q" to the function
> which
> would mean that the union is passed by value, right? Is this really
> what
> you want? Why not pass-though just the pointer to the union?
>
I used
rpmTagData *q = (void *)&p;
and then later
..., *q, ...
Turned out I had written
typedef const hRET_t rpmTagData;
Note the "const".
Once I figgered the sloppiness, casts for unions started to behave ;-)
Still, union ptrs are a bit bizzare, e.g.
(*he->p).str = "some string"
rather than the (more natural to me, not C ;-)
*he->p.str = "some string";
There's still 1 level of indirection I need to eliminate
to push rpmTagData back into a HE_t.
And enum typedef's are kinda wonky too. E.g.
typedef enum rpmTag_e rpmTag;
...
rpmTag foo;
won't "work" unless enum rpmTag_e is known when typedef is 1st used.
Ah well, I'm just a carpenter, not a pedant. ptrs is ptrs and ints is
ints, that's
all I really need to hammer out a solution.
Still, getting rpmTagFoo private typedefs means gcc is actually helping
find coding problems, that's already a win.
Anyone for bit fields? There's actually a need for arbitrary named bits
in tags with
Requires(foo): ....
73 de Jeff
Received on Wed Oct 17 23:57:22 2007