James Kuyper
9/6/2011 9:44:00 PM
On 09/06/2011 05:01 PM, Quentin Pope wrote:
> We know that &struct is equiv to &struct.firstMember. So far so good.
Not true. Those two pointers have different types, and correspondingly
different behavior when dereferenced, so they are not equivalent. A more
accurate statement would be
(firstmember_type*)&struct == &struct.firstMember
and also:
&struct == (struct struct_tag*)&struct.firstMember
Note: if firstMember is a bit-field, &struct.firstMember is a constraint
violation, and these guarantees don't hold.
> Now I have an union
> union r32{
> uint8 l;
> uint16 x;
> uint32 val;
If you're using C99, you should #include <stdint.h> and replace these
with uint8_t, uint16_t, uint32_t. These types are not guaranteed to be
supported, though they should in fact be supported on almost all
implementations. If a serious C99 implementation does not provide those
types on given platform, you can reasonably assume that it's extremely
difficult, perhaps even impossible, to provide those types on that
platform. You can check whether or not they are supported by
#if !defined(UINT8_MAX) || !defined(UINT16_MAX) || !defined(UINT32_MAX)
#error uint8_t, uint16_t or uint32_t not supported.
#endif
> };
>
> union r32 reg;
>
> and a function
> void f(union r32* a){a->x=1;}
>
> then
>
> is to do f(®.x) or f(®.l) or f(®.val) OK or not?
With a function prototype in scope, all of those pointers are implicitly
converted to union r32* when passed to that function. The result of that
conversion is guaranteed to point at the containing union, so all three
are OK.
> is it ®.x=®.l=®.val ?
No, but
(union r32*)®.x == (union r32*)®.l
and similarly for the other combinations. It's also true that
(uint32*)(union r32*)®.x == ®.val
It would seem obvious that this means that
(uint32*)®.x == ®.val
and this is indeed true on (almost?) all implementations of C. However,
the standard does not actually guarantee that (uint32*)(union r32*)
produces the same result as (uint32*).
> Or I have to do f(®)?
While you do not have to use ®, I would strongly recommend it unless
you have a compelling need to use something else.