RoSsIaCrIiLoIA wrote:
I have a union
union r32{
uint8_t l;
uint16_t x;
uint32_t val;
I'll assume the `uintxxx' are typedefs.
};
union r32 reg;
and a function
void f(union r32* a){a->x=1;}
then
to do f(®.x) or f(®.l) or f(®.val) is good or not?
Not valid as written. f() expects a `union r32*'
argument, and these three calls provide a `uint8_t*',
a `uint16_t*', and a `uint32_t*'. These pointer types
are not compatible with `union r32*'.
A union pointer can be converted to a pointer to
any of its members, and vice versa, but you must write
the conversion explicitly:
f( (union r32*) ®.x )
.... which is pretty silly, but it works.
is it ®.x=®.l=®.val ?
I'll assume you're asking about comparing the pointer
values, not somehow assigning them. Pointers can't be
compared unless they have compatible types, so the
compiler will object if you attempt `®.x == ®.l'
(unless the `uintxxx' typedefs are aliases for the same
underlying C type, which seems rather unlikely).
If you convert the pointer values to a legitimate
common type -- `void*' or `union r32*' or `char*', for
example -- then all three of these will compare equal.
Or I have to do f(®)?
You don't *have* to, but it's certainly easiest.
Thank you
Judging from the context, you're hoping to do some
type-punning by placing a bunch of different objects in
a union, storing a value in one of them, and retrieving
another. Unfortunately, that invokes undefined behavior
(except in a special circumstance involving structs,
which doesn't seem to apply here). You will get away
with this dubious practice on many compilers -- but be
prepared for inexplicable breakage, especially if the
compiler uses aggressive optimizations.
--
Er*********@sun.com