RPM Community Forums

Mailing List Message of <rpm-devel>

Re: Cast for a union C question.

From: Ralf S. Engelschall <rse+rpm-devel@rpm5.org>
Date: Wed 17 Oct 2007 - 19:08:44 CEST
Message-ID: <20071017170844.GA28380@engelschall.com>
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?

                                       rse@engelschall.com
                                       www.engelschall.com
Received on Wed Oct 17 19:11:52 2007
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.