Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #10206

Re: Order of UNION members (was Re: UNION global variabl initialize)

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>

Show all headers | View raw


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


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