is this a valid approach to aliasing?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After twenty years of programming in C, I thought I understood the language pretty well until some new code I was writing started emitting "type-punned pointer" aliasing warnings. So I read up on the problem so I would understand it. I understand that is necessary to restrict aliasing in order to optimize/load stores.

My question is if my solution to the problem is valid. Basically, I had some functionality I wanted to abstract which became the following function:

int reallocItems(void **items, int itemSize, int *itemAlloc, int numItems, int newItems, int itemHint)
{
    void *rcAlloc;
    int emptyItems, allocItems;

    // for idempotence
    allocItems = *itemAlloc;

    // will the new entries fit?
    //
    emptyItems = allocItems - numItems;
    if (newItems > emptyItems) {

// allocate the number of entries needed or the hint, whichever is more
        //
        allocItems = numItems + newItems;
        if (itemHint > allocItems) {
            allocItems = itemHint;
        }

        rcAlloc = (void *) realloc(*items, allocItems * itemSize);
        if (rcAlloc) {

            *items = rcAlloc;
            *itemAlloc = allocItems;

        } else {
            return -1;
        }
    }

    return 0;
}

Naturally, when I started trying to call this function, I started getting the type-punned pointer aliasing warnings. The code in question looked roughly like this:

static opt_param_t *shrtOpts, *longOpts;

rc = reallocItems((void **) &shrtOpts, sizeof(opt_param_t), &shrtOptAlloc, numShrtOpts, newShrtOpts, shrtOptHint);

Obviously, this breaks the aliasing rules. I read that I could work around this by casting through a union. I settled on this approach, but I'm not sure if it is valid, or if I'm merely masking the problem:

typedef union _opt_param_alias_t {

    opt_param_t *o;
    void *v;

} opt_param_alias_t;

rc = reallocItems(&((opt_param_alias_t *) &shrtOpts)->v, sizeof(opt_param_t), &shrtOptAlloc, numShrtOpts, newShrtOpts, shrtOptHint)

Will casting through this union force the compiler to reload the address of shrtOpts when I try to reference it a few lines later? Is this solution correct? Is there a better approach that does NOT involve changing reallocItems to return a void pointer?

I tried several different approaches, and I'm trying to find an approach that requires little extra code and does not ugly things up too much.

Please advise.  Thank you.

Regards,

Rob


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux