tech-kern archive

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

Re: proposal: some pointer and arithmetic utilities



On Thu, Mar 21, 2013 at 08:29:46PM +0000, Taylor R Campbell wrote:
>    Date: Thu, 21 Mar 2013 21:11:56 +0100
>    From: Rhialto <rhialto%falu.nl@localhost>
> 
>    I would argue that all such mumble() should really be changed to
> 
>            int
>            mumble(struct foo *foo)
>            {
>                    struct bar *bar = &foo->f_bar;
>                    ...
>            }
> 
>    since they are making that assumption already anyway.
> 
> This transformation doesn't make sense when the caller of mumble works
> with bars, not foos, and it's the caller of the caller of mumble that
> needs to pass in a foo to mumble by way of passing a bar to the caller
> of mumble.
> 
> For example, consider workqueues and struct work.  If you want to put
> an object on a workqueue (i.e., pass an argument in a request for
> deferred work), you embed a struct work in the object and then the
> workqueue's worker takes the struct work and finds the containing
> object from of it.
> 
> kern_physio.c relies on the fact that the struct work is at the
> beginning of struct buf when it does
> 
> static void
> physio_done(struct work *wk, void *dummy)
> {
>       struct buf *bp = (void *)wk;
>       ...
> }
> 
> to recover bp after workqueue_enqueue(physio_workqueue, &bp->b_work,
> NULL).  But instead it could use
> 
>       struct buf *bp = container_of(wk, struct work, b_work);

I think you meant container_of(wk, struct buf, b_work) ?

Sometimes I wish that the C language had a notation for that
container_of() expression looking like this,

        &bp->b_work = wk;

In the LHS expression, `bp' is the only free variable, so it gets set in
order for `wk' to equal `&bp->b_work'.

An analogous expression for an array is more ambiguous than the previous
example,

        /*
         * Return the index of the `array' element pointed to by `elt'.
         */
        int
        indexof(const int *array, const int *elt)
        {
                int i;

                &array[i] = elt;

                return i;
        }

because there are two free variables, `array' and `i'.  The compiler
should flag that as an error.  I guess we can eliminate the ambiguity in
a couple of ways.  One way is to const-ify array,

        int
        indexof(const int * const array, const int *elt)
        {
                int i;

                &array[i] = elt;

                return i;
        }

Another way is to cast to const,

        int
        indexof(const int *array, const int *elt)
        {
                int i;

                &((const int * const)array)[i] = elt;

                return i;
        }

Dave

-- 
David Young
dyoung%pobox.com@localhost    Urbana, IL    (217) 721-9981


Home | Main Index | Thread Index | Old Index