Barry Briggs
8/31/2011 8:04:00 AM
James Kuyper wrote:
> On 08/24/2011 11:45 AM, Noob wrote:
>> Hello,
>>
>> I've tried to translate real code into something
>> small enough to discuss here. Hopefully, it still
>> makes some sense...
>>
>> Consider the following.
>>
>> Two unrelated structs:
>> struct desc { int a,b,c,d; };
>> struct pbuf { int e,f,g; };
>>
>> A struct which "extends" 'struct pbuf':
>> struct pbuf2 { struct pbuf x; int y; };
>>
>> And a struct that "binds" 'struct desc' and 'struct pbuf2':
>> struct foo { struct pbuf2 xx; struct desc yy; }
>>
>> Finally consider a callback function
>> void callback_fun(struct pbuf *p)
>>
>> At some point in my code, I have a 'struct foo' object,
>> (say struct foo toto)
>>
>> I pass q = &toto.pbuf2.x (a struct pbuf pointer) to some
>
> I'll assume that you meant &toto.xx.x?
You're right. I should have used simpler names, such as
struct pbuf2 { struct pbuf pbuf; int y; };
struct foo { struct pbuf2 pbuf2; struct desc desc; }
>> API function, and "sometime later" (threads involved)
>> the library will call callback_fun(q)
>>
>> I need to "retrieve" toto.yy from callback_fun's parameter.
>>
>> Is it safe to do
>> void callback_fun(struct pbuf *p)
>> {
>> struct foo *toto = (struct foo *)p;
>> /* use toto->desc */
>> }
>
> Conversion of a pointer to the first member of a struct to the type of
> the struct is guaranteed to produce a valid pointer to the containing
> struct object. Therefore, it would be absolutely safe to do the following:
>
> struct foo *toto = (struct foo*)(struct pbuf2*)p;
I never thought I would ever see a legitimate reason to write
two casts on the same line. I had always assumed that it would
be sufficient to have only the first cast, i.e. the final type.
> Technically, the standard does NOT guarantee that (struct foo*)(struct
> pbuf2*) will produce the same result as a direct cast to (struct foo*).
> However, in practice it should work.
I see.
Thanks for the detailed answer!
Regards.