Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Date | 2011-09-13 17:45 -0400 |
| Organization | A noiseless patient Spider |
| Message-ID | <4E6FCEF5.20608@verizon.net> (permalink) |
| References | <8808246d-5605-4a5d-b8a2-ae7267769aed@glegroupsg2000goo.googlegroups.com> <chine.bleu-E5236F.22342012092011@news.eternal-september.org> <1omdnQdZDazPIPLTnZ2dnUVZ_rGdnZ2d@bestweb.net> |
On 09/13/2011 04:29 PM, Kenneth Brody wrote:
> On 9/13/2011 1:34 AM, China Blue Corn Chips wrote:
>> In article
>> <8808246d-5605-4a5d-b8a2-ae7267769aed@glegroupsg2000goo.googlegroups.com>,
>> "Lung.S.Wu"<lung.s.wu@gmail.com> wrote:
>>
>>> 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
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
UNION global variabl initialize "Lung.S.Wu" <lung.s.wu@gmail.com> - 2011-09-12 09:38 -0700
Re: UNION global variabl initialize jt@toerring.de (Jens Thoms Toerring) - 2011-09-12 17:08 +0000
Re: UNION global variabl initialize Kenneth Brody <kenbrody@spamcop.net> - 2011-09-12 15:02 -0400
Re: UNION global variabl initialize "Lung.S.Wu" <lung.s.wu@gmail.com> - 2011-09-12 22:10 -0700
Re: UNION global variabl initialize Ike Naar <ike@iceland.freeshell.org> - 2011-09-13 07:10 +0000
Re: UNION global variabl initialize jt@toerring.de (Jens Thoms Toerring) - 2011-09-13 11:42 +0000
Re: UNION global variabl initialize Robert Wessel <robertwessel2@yahoo.com> - 2011-09-13 13:34 -0500
Re: UNION global variabl initialize China Blue Corn Chips <chine.bleu@yahoo.com> - 2011-09-12 22:34 -0700
Re: UNION global variabl initialize "Lung.S.Wu" <lung.s.wu@gmail.com> - 2011-09-12 23:07 -0700
Re: UNION global variabl initialize China Blue Corn Chips <chine.bleu@yahoo.com> - 2011-09-12 23:35 -0700
Re: UNION global variabl initialize James Kuyper <jameskuyper@verizon.net> - 2011-09-13 08:09 -0400
Order of UNION members (was Re: UNION global variabl initialize) Kenneth Brody <kenbrody@spamcop.net> - 2011-09-13 16:29 -0400
Re: Order of UNION members (was Re: UNION global variabl initialize) James Kuyper <jameskuyper@verizon.net> - 2011-09-13 17:45 -0400
Re: Order of UNION members (was Re: UNION global variabl initialize) "Lung.S.Wu" <lung.s.wu@gmail.com> - 2011-09-13 19:32 -0700
Re: Order of UNION members (was Re: UNION global variabl initialize) James Kuyper <jameskuyper@verizon.net> - 2011-09-14 06:59 -0400
Re: Order of UNION members (was Re: UNION global variabl initialize) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-14 15:08 +0100
Re: Order of UNION members (was Re: UNION global variabl initialize) Kenneth Brody <kenbrody@spamcop.net> - 2011-09-14 12:50 -0400
Re: Order of UNION members (was Re: UNION global variabl initialize) James Kuyper <jameskuyper@verizon.net> - 2011-09-14 13:21 -0400
csiph-web