Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #10155 > unrolled thread
| Started by | "Lung.S.Wu" <lung.s.wu@gmail.com> |
|---|---|
| First post | 2011-09-12 09:38 -0700 |
| Last post | 2011-09-14 13:21 -0400 |
| Articles | 18 — 8 participants |
Back to article view | Back to comp.lang.c
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
| From | "Lung.S.Wu" <lung.s.wu@gmail.com> |
|---|---|
| Date | 2011-09-12 09:38 -0700 |
| Subject | UNION global variabl initialize |
| Message-ID | <8808246d-5605-4a5d-b8a2-ae7267769aed@glegroupsg2000goo.googlegroups.com> |
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
1 typedef union {
2 char a;
3 short b;
4 int c;
5 } UU;
6
7 UU u;
8
9 int main(void)
10 {
11
12 return 0;
13 }
Only the member u.a is initialized as 0, And others are undefined.
But from modern system design (ELF), all memory of the global variable u will be cleared to 0. Because u is saved at BSS, and program loader will clear BSS segment after a executable file is load into main memory.
My question...
1. Does exist any system that will not clear remain elements of global union variable?
2. Why ANSI C org. will not define all union members be cleared to zero?
[toc] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-09-12 17:08 +0000 |
| Message-ID | <9d6skcF5t1U1@mid.uni-berlin.de> |
| In reply to | #10155 |
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
> 1 typedef union {
> 2 char a;
> 3 short b;
> 4 int c;
> 5 } UU;
> 6
> 7 UU u;
> 8
> 9 int main(void)
> 10 {
> 11
> 12 return 0;
> 13 }
> Only the member u.a is initialized as 0, And others are undefined.
> But from modern system design (ELF), all memory of the global variable
> u will be cleared to 0. Because u is saved at BSS, and program loader
> will clear BSS segment after a executable file is load into main memory.
That may be the case for a number of systems, but the C standard
isn't made for a sub-class of the exising systems, it tries to
address, as far as possible, all kinds of systems.
> My question...
> 1. Does exist any system that will not clear remain elements of global
> union variable?
> 2. Why ANSI C org. will not define all union members be cleared to zero?
There are definitely systems where e.g. a floating point value
or a NULL pointer has a representation that's not all-bits-zero.
If on such a system you have a union that contains one of those
as well as a member that has an all-bit-zero representation it
would be impossible to initialize both members at the same time
to a "zero" value. Thus it would be counterproductive if the C
standard would request that more than a single element is initi-
alized to a "zero" value since it would make it impossible to
write a conforming compiler for such a system
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-09-12 15:02 -0400 |
| Message-ID | <MeWdnbUoe7HpyvPTnZ2dnUVZ_vidnZ2d@bestweb.net> |
| In reply to | #10155 |
On 9/12/2011 12:38 PM, Lung.S.Wu 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
> 1 typedef union {
> 2 char a;
> 3 short b;
> 4 int c;
> 5 } UU;
> 6
> 7 UU u;
> 8
> 9 int main(void)
> 10 {
> 11
> 12 return 0;
> 13 }
> Only the member u.a is initialized as 0, And others are undefined.
>
> But from modern system design (ELF), all memory of the global variable u will be cleared to 0. Because u is saved at BSS, and program loader will clear BSS segment after a executable file is load into main memory.
>
> My question...
> 1. Does exist any system that will not clear remain elements of global union variable?
> 2. Why ANSI C org. will not define all union members be cleared to zero?
Well, as answered elsethread, it may not be possible to initialize all
elements to zero. (ie: a system where NULL is not all-bits-zero.)
Consider, too, what happens if the first named element is a pointer on such
a system. You can't use BSS on such a system (assuming that BSS even exists
on such a system) because it's not initialized to all-bits-zero.
union {
char *pt;
int (*func)(void);
float f;
double d;
}
foo;
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | "Lung.S.Wu" <lung.s.wu@gmail.com> |
|---|---|
| Date | 2011-09-12 22:10 -0700 |
| Message-ID | <5c936754-ed82-406e-a9e9-aab7ccc97d0c@glegroupsg2000goo.googlegroups.com> |
| In reply to | #10161 |
Yes, agree with you. Is there any system which defines NULL, floating point 0 not all bits-zero?
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2011-09-13 07:10 +0000 |
| Message-ID | <slrn3vfsj6u0ev.a21.ike@iceland.freeshell.org> |
| In reply to | #10171 |
On 2011-09-13, Lung.S.Wu <lung.s.wu@gmail.com> wrote: > Is there any system which defines NULL, floating point 0 not all bits-zero? This is a FAQ. http://c-faq.com/null/machexamp.html
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2011-09-13 11:42 +0000 |
| Message-ID | <9d8tslF4ukU1@mid.uni-berlin.de> |
| In reply to | #10179 |
Ike Naar <ike@iceland.freeshell.org> wrote:
> On 2011-09-13, Lung.S.Wu <lung.s.wu@gmail.com> wrote:
> > Is there any system which defines NULL, floating point 0 not all bits-zero?
> This is a FAQ.
> http://c-faq.com/null/machexamp.html
And I remember to have read that on 286 and 386 machines without
a math co-processor floating point operations were done via soft-
ware emulation using a non-IEEE 754 format where 0.0 had a non-
all-bits-zero representation (but I may mis-remember, never ha-
ving used that kind of machines;-). And, while I have no expe-
rience with embedded systems, I wouldn't be too surprised if
one would find something similar on those. Furthermore, there
is nothing that keeps people developing new architectures that
don't use IEEE 754 or have non-zero NULL pointers...
So it's not really so much the question if such machines exit
but that, since the C standard doesn't require an all-bits-zero
representation for NULL pointers and 0.0 floating point values
(maybe mostly for historical reasons) it simply can't mandate
that more than one member of a static union is initialized to
a "zero" value.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2011-09-13 13:34 -0500 |
| Message-ID | <ml7v671cfvf7sjun5s56qu0e4qafban9jg@4ax.com> |
| In reply to | #10184 |
On 13 Sep 2011 11:42:13 GMT, jt@toerring.de (Jens Thoms Toerring)
wrote:
>Ike Naar <ike@iceland.freeshell.org> wrote:
>> On 2011-09-13, Lung.S.Wu <lung.s.wu@gmail.com> wrote:
>> > Is there any system which defines NULL, floating point 0 not all bits-zero?
>
>> This is a FAQ.
>> http://c-faq.com/null/machexamp.html
>
>And I remember to have read that on 286 and 386 machines without
>a math co-processor floating point operations were done via soft-
>ware emulation using a non-IEEE 754 format where 0.0 had a non-
>all-bits-zero representation (but I may mis-remember, never ha-
>ving used that kind of machines;-). And, while I have no expe-
>rience with embedded systems, I wouldn't be too surprised if
>one would find something similar on those. Furthermore, there
>is nothing that keeps people developing new architectures that
>don't use IEEE 754 or have non-zero NULL pointers...
>
>So it's not really so much the question if such machines exit
>but that, since the C standard doesn't require an all-bits-zero
>representation for NULL pointers and 0.0 floating point values
>(maybe mostly for historical reasons) it simply can't mandate
>that more than one member of a static union is initialized to
>a "zero" value.
While I certainly can't speak to all of the float formats ever
implemented on x86 software (and there were more than a few), MS's
main "pre-IEEE" format ("MBF" - ignoring the decimal float support in
some of their early products) did treat an all-bits-zero number as
zero (actually anything with a zero exponent field).
But the most common emulated FP format on x86 was, in fact, IEEE, just
done in software. The 8087 became available around the same time the
original IBM PC shipped (perhaps a year before), and the PC had a
coprocessor socket from day one (although it was not "officially" an
8087 socket at first). So the emulation libraries often had an option
for doing emulation, or actually using the coprocessor, if it was
present. At some point the emulation was actually moved into the OS
for MS products, and applications could just be coded with x87
instructions, and the OS would either emulate or just let the
instructions execute on the FPU.
Some folks did other things for performance if there was no
coprocessor, and there were even non-8087 compatible FPUs.
Ignoring that the 8087 predated the final IEEE math spec, and didn't
quite implement what we'd call IEEE math today (or at least even less
so than today's "8087s").
Of course many of the floating point formats have multiple zeros, but
MBF and IEEE, at least, will treat all-bits-zero as a zero.
[toc] | [prev] | [next] | [standalone]
| From | China Blue Corn Chips <chine.bleu@yahoo.com> |
|---|---|
| Date | 2011-09-12 22:34 -0700 |
| Message-ID | <chine.bleu-E5236F.22342012092011@news.eternal-september.org> |
| In reply to | #10155 |
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
> 1 typedef union {
> 2 char a;
> 3 short b;
> 4 int c;
> 5 } UU;
> 6
> 7 UU u;
> 8
> 9 int main(void)
> 10 {
> 11
> 12 return 0;
> 13 }
> 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}
>
> But from modern system design (ELF), all memory of the global variable u will
> be cleared to 0. Because u is saved at BSS, and program loader will clear BSS
> segment after a executable file is load into main memory.
>
> My question...
> 1. Does exist any system that will not clear remain elements of global union
> variable?
> 2. Why ANSI C org. will not define all union members be cleared to zero?
--
I remember finding out about you, |With the nutty taste of wild hickory nuts.
Everyday my mind is all around you,| I'm whoever you want me to be.
Looking out from my lonely room | Annoying Usenet one post at a time.
Day after day. | At least I can stay in character.
Celle est une langue. C'est francais et tres, tres sexuel.
[toc] | [prev] | [next] | [standalone]
| From | "Lung.S.Wu" <lung.s.wu@gmail.com> |
|---|---|
| Date | 2011-09-12 23:07 -0700 |
| Message-ID | <90086c21-4f53-443b-93c4-5e2facd12d7b@glegroupsg2000goo.googlegroups.com> |
| In reply to | #10172 |
China Blue Corn Chips於 2011年9月13日星期二UTC+8下午1時34分20秒寫道:
> In article
> <8808246d-5605-4a5d...@glegroupsg2000goo.googlegroups.com>,
> "Lung.S.Wu" <lung...@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
> > 1 typedef union {
> > 2 char a;
> > 3 short b;
> > 4 int c;
> > 5 } UU;
> > 6
> > 7 UU u;
> > 8
> > 9 int main(void)
> > 10 {
> > 11
> > 12 return 0;
> > 13 }
> > 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}
Yes, This is C99 defined.
My working environment cross GNU C, VS 2005/2008. VS does not support this kind of initialize.
>
>
> >
> > But from modern system design (ELF), all memory of the global variable u will
> > be cleared to 0. Because u is saved at BSS, and program loader will clear BSS
> > segment after a executable file is load into main memory.
> >
> > My question...
> > 1. Does exist any system that will not clear remain elements of global union
> > variable?
> > 2. Why ANSI C org. will not define all union members be cleared to zero?
>
> --
> I remember finding out about you, |With the nutty taste of wild hickory nuts.
> Everyday my mind is all around you,| I'm whoever you want me to be.
> Looking out from my lonely room | Annoying Usenet one post at a time.
> Day after day. | At least I can stay in character.
> Celle est une langue. C'est francais et tres, tres sexuel.
[toc] | [prev] | [next] | [standalone]
| From | China Blue Corn Chips <chine.bleu@yahoo.com> |
|---|---|
| Date | 2011-09-12 23:35 -0700 |
| Message-ID | <chine.bleu-B21108.23351412092011@news.eternal-september.org> |
| In reply to | #10173 |
In article
<90086c21-4f53-443b-93c4-5e2facd12d7b@glegroupsg2000goo.googlegroups.com>,
"Lung.S.Wu" <lung.s.wu@gmail.com> wrote:
> China Blue Corn Chips於 2011年9月13日星期二UTC+8下午1時34分20秒寫道:
> > In article
> > <8808246d-5605-4a5d...@glegroupsg2000goo.googlegroups.com>,
> > "Lung.S.Wu" <lung...@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
> > > 1 typedef union {
> > > 2 char a;
> > > 3 short b;
> > > 4 int c;
> > > 5 } UU;
> > > 6
> > > 7 UU u;
> > > 8
> > > 9 int main(void)
> > > 10 {
> > > 11
> > > 12 return 0;
> > > 13 }
> > > 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}
> Yes, This is C99 defined.
> My working environment cross GNU C, VS 2005/2008. VS does not support this
> kind of initialize.
#define u (*u_())
static UU *u_(void) {
static UU u0; static int first = 1;
if (first) {
memset(&u0,0,sizeof u0);
first = 0;
}
return &u0;
}
--
I remember finding out about you, |With the nutty taste of wild hickory nuts.
Everyday my mind is all around you,| I'm whoever you want me to be.
Looking out from my lonely room | Annoying Usenet one post at a time.
Day after day. | At least I can stay in character.
Celle est une langue. C'est francais et tres, tres sexuel.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-13 08:09 -0400 |
| Message-ID | <j4nh5l$s3d$1@dont-email.me> |
| In reply to | #10173 |
On 09/13/2011 02:07 AM, Lung.S.Wu wrote:
> China Blue Corn Chips於 2011年9月13日星期二UTC+8下午1時34分20秒寫道:
>> In article
>> <8808246d-5605-4a5d...@glegroupsg2000goo.googlegroups.com>,
>> "Lung.S.Wu" <lung...@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
>>> 1 typedef union {
>>> 2 char a;
>>> 3 short b;
>>> 4 int c;
>>> 5 } UU;
>>> 6
>>> 7 UU u;
>>> 8
>>> 9 int main(void)
>>> 10 {
>>> 11
>>> 12 return 0;
>>> 13 }
>>> 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}
> Yes, This is C99 defined.
> My working environment cross GNU C, VS 2005/2008. VS does not support this kind of initialize.
Then another alternative is to make the member that you want initialized
to 0 be the first element in the union. This won't help, of course, if
the element you want 0-initialized is different in different contexts.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-09-13 16:29 -0400 |
| Subject | Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <1omdnQdZDazPIPLTnZ2dnUVZ_rGdnZ2d@bestweb.net> |
| In reply to | #10172 |
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.
Of course, doing so, just to make the "correct" member be initialized to
zero, would be "unusual" to say the least.
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-13 17:45 -0400 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <4E6FCEF5.20608@verizon.net> |
| In reply to | #10202 |
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
[toc] | [prev] | [next] | [standalone]
| From | "Lung.S.Wu" <lung.s.wu@gmail.com> |
|---|---|
| Date | 2011-09-13 19:32 -0700 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <46f7e7d5-814d-427c-aa89-084e28f387d2@glegroupsg2000goo.googlegroups.com> |
| In reply to | #10206 |
If each member will be cleared to zero. Will it be better with such code?
4 typedef union {
5 int i;
6 float f;
7 char *pt;
8 } bfoo;
9
10 union f {
11 char align[sizeof(bfoo)];
12 bfoo foo;
13 };
14
15 union f fff;
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-14 06:59 -0400 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <j4q1ds$fb7$1@dont-email.me> |
| In reply to | #10210 |
On 09/13/2011 10:32 PM, Lung.S.Wu wrote:
> If each member will be cleared to zero. Will it be better with such code?
The only member guaranteed to be "cleared to zero" when a union object
is default-initialized is the first member; that's the point of this thread.
> 4 typedef union {
> 5 int i;
> 6 float f;
> 7 char *pt;
> 8 } bfoo;
> 9
> 10 union f {
> 11 char align[sizeof(bfoo)];
> 12 bfoo foo;
> 13 };
> 14
> 15 union f fff;
The standard guarantees that default initialization of fff sets every
element of fff.align to 0. This is sufficient to ensure that
fff.foo.i==0, but provides no similar guarantees for fff.foo.f or
fff.foo.pt. This doesn't seem like any substantial improvement over the
guarantees that you get for a default-initialized object of type bfoo.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-09-14 15:08 +0100 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <0.a423fc928d6d5fb101f2.20110914150851BST.87fwjzz05o.fsf@bsb.me.uk> |
| In reply to | #10214 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 09/13/2011 10:32 PM, Lung.S.Wu wrote:
>> If each member will be cleared to zero. Will it be better with such code?
>
> The only member guaranteed to be "cleared to zero" when a union object
> is default-initialized is the first member; that's the point of this thread.
>
>> 4 typedef union {
>> 5 int i;
>> 6 float f;
>> 7 char *pt;
>> 8 } bfoo;
>> 9
>> 10 union f {
>> 11 char align[sizeof(bfoo)];
>> 12 bfoo foo;
>> 13 };
>> 14
>> 15 union f fff;
>
> The standard guarantees that default initialization of fff sets every
> element of fff.align to 0. This is sufficient to ensure that
> fff.foo.i==0, but provides no similar guarantees for fff.foo.f or
> fff.foo.pt. This doesn't seem like any substantial improvement over the
> guarantees that you get for a default-initialized object of type bfoo.
The main one (not great, I admit) is that if sizeof(char *) or
sizeof(float) is > sizeof(int) they too get zero-bit initialised. If
you know that zero-bits equals zero, that may be enough for you. I an
not sure there's much use for this, but it is a small advantage.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-09-14 12:50 -0400 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <vLadnb80m_XhRu3TnZ2dnUVZ_gmdnZ2d@bestweb.net> |
| In reply to | #10206 |
On 9/13/2011 5:45 PM, James Kuyper wrote:
> On 09/13/2011 04:29 PM, Kenneth Brody wrote:
[...]
>> 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
[...]
Okay, but I think of that as one of those generic "you lied to the compiler
when you told it that these two pointers never point to the same object"
type of situations. :-)
[...]
>> 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.
I find it hard to believe that the Standard would allow the following:
===== fileA.C
union foo {
int i;
float f;
char *pt;
};
...
===== fileB.C
union foo {
float f;
char *pt;
int i;
};
union bar {
float f;
char *pt;
int i;
};
=====
And have unions "foo" and "bar" in fileB.C not be equivalent. And, if
fileB's bar is equivalent to its foo, and its foo is equivalent to fileA's
foo, then fileB's foo must also be equivalent to fileA's foo.
And, if fileB's foo is removed, its bar still remains equivalent.
That's not to say you can convert a "foo*" to a "bar*" without an explicit
cast. It's just that the cast is perfectly legal, and invokes no
non-standard behavior.
[...]
Again, I can't see actually doing such a thing just to default-initialize a
different "first" member.
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-14 13:21 -0400 |
| Subject | Re: Order of UNION members (was Re: UNION global variabl initialize) |
| Message-ID | <4E70E2B2.703@verizon.net> |
| In reply to | #10230 |
On 09/14/2011 12:50 PM, Kenneth Brody wrote:
> On 9/13/2011 5:45 PM, James Kuyper wrote:
>> On 09/13/2011 04:29 PM, Kenneth Brody wrote:
> [...]
>>> 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
> [...]
>
> Okay, but I think of that as one of those generic "you lied to the compiler
> when you told it that these two pointers never point to the same object"
> type of situations. :-)
But I didn't; that would be equivalent to using the 'restrict' keyword,
which would enable the same optimization, regardless of the type of pb.
All that I promised is that the pointers never point to objects of the
same type. It is section 6.5p7 which, as a result of the fact that these
pointers do not point at compatible types, implies that they therefore
cannot point at the same object.
>>> 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.
>
> I find it hard to believe that the Standard would allow the following:
>
> ===== fileA.C
>
> union foo {
> int i;
> float f;
> char *pt;
> };
>
> ...
>
> ===== fileB.C
>
> union foo {
> float f;
> char *pt;
> int i;
> };
>
> union bar {
> float f;
> char *pt;
> int i;
> };
>
> =====
>
> And have unions "foo" and "bar" in fileB.C not be equivalent.
I agree that they are "equivalent" in many ways. However, they're not
required to be compatible, and as a result there's a number of
associated guarantees in the standard that do NOT apply - the most
important that I can think of being the aliasing issue I've already
raised. As a result, you cannot safely use one in place of the other,
which means that they are not equivalent for all purposes.
> ... And, if
> fileB's bar is equivalent to its foo, and its foo is equivalent to fileA's
> foo, then fileB's foo must also be equivalent to fileA's foo.
>
> And, if fileB's foo is removed, its bar still remains equivalent.
>
> That's not to say you can convert a "foo*" to a "bar*" without an explicit
> cast. It's just that the cast is perfectly legal, and invokes no
> non-standard behavior.
There's nothing in the standard that guarantees that the unions have the
same alignment requirements - though there's obviously no reason for
them being different. In principle, therefore, even the cast is not
guaranteed to be safe.
However, the more serious problem is that dereferencing the resulting
pointer value violates 6.5p7 because the standard doesn't say that foo
and bar are compatible types.
...
> Again, I can't see actually doing such a thing just to default-initialize a
> different "first" member.
Agreed. Explicitly initializing the desired member seems the more
appropriate solution, even in C90, where you have to do so outside the
initializer.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web