Lung.S.Wu said:
From ANSI C definition, section 6.7.8, with UNION, it says that only the
first named element will be initialized if it is not initialized explicitly.
That means, such the code [...]
Only the member u.a is initialized as 0, And others are undefined.
If you want to depend on an initialisation, do so explicitly,
UU u = {.c = 0}
[...]
Question:
If one defines two different unions, consisting of the same members, but in
a different order, are they guaranteed to be equivalent?
union foo {
int i;
float f;
char *pt;
};
union bar {
char *pt;
int i;
float f;
};
Given 6.7.2.1p14, I would think so:
A pointer to a union object, suitably converted, points to each of its
members (or if a member is a bitfield, then to the unit in which it
resides), and vice versa.
That's quite plausible, but the standard makes no guarantees about it.
In particular, it does not say that union foo is compatible with union
bar. Among other implications is that a conforming implementation of C
is not required to consider the possibility that an a union foo* and a
union bar* might alias each other. Consider the following code:
void func(union foo *pf, union bar *pb)
{
for(; pf->i; pf++)
pf->i = pb->i;
}
A conforming implementation of C could optimize that code into the
equivalent of
void func(union foo *pf, union bar *pb)
{
int i = pb->i;
for(; pf->i; pf++)
pf->i = i;
}
Such an optimization would not be permissible if you changed "union bar"
to "union foo", because pb == pf might be true at some point during the
loop. That's a possibility that the implementation is not required to
take into consideration if pf and pb point to incompatible types.
Of course, doing so, just to make the "correct" member be initialized to
zero, would be "unusual" to say the least.
6.2.7p1:
"Moreover, two structure, union, or enumerated types declared in
separate translation units are compatible if their tags and members
satisfy the following requirements: If one is declared with a tag, the
other shall be declared with the same tag. If both are complete types,
then the following additional requirements apply: there shall be a
one-to-one correspondence between their members such that each pair of
corresponding members are declared with compatible types, and such that
if one member of a corresponding pair is declared with a name, the
other member is declared with the same name. For two structures,
corresponding members shall be declared in the same order. For two
structures or unions, corresponding bit-fields shall have the same widths."
Note that if "union foo" and "union bar" had been given the same tag in
different translation units, they would have be compatible. The
requirement that the members be declared in the same order applies only
to structures, not to unions or enumerations.
Here's one possible way to take advantage of that fact:
reorderable_union.h:
#ifndef REORDERABLE_H
#define REORDERABLE_H
union reorderable {
#if defined(INT_FIRST)
int i;
float f;
char *pt;
#elif defined(FLOAT_FIRST)
float f;
int i;
char *pt;
#else
char *pt;
int i;
float f;
#endif
};
#endif