[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

union field access

Edward Rutherford

5/27/2011 8:59:00 PM

If I have an union

union U {
struct X x;
struct Y y;
struct Z z;

} u;

and both struct Y and struct Z have a struct X as the first field, then
can I always access u.x.<field> even if I am actually putting a struct Y
or Z in u?
14 Answers

Shao Miller

5/27/2011 9:12:00 PM

0

On 5/27/2011 16:58, Edward Rutherford wrote:
> If I have an union
>
> union U {
> struct X x;
> struct Y y;
> struct Z z;
>
> } u;
>
> and both struct Y and struct Z have a struct X as the first field, then
> can I always access u.x.<field> even if I am actually putting a struct Y
> or Z in u?

Yes. It's called "type punning," if I'm not mistaken.

"82) If the member used to access the contents of a union object is not
the same as the member last used to store a value in the object, the
appropriate part of the object representation of the value is
reinterpreted as an object representation in the new type as described
in 6.2.6 (a process sometimes called "type punning"). This might be a
trap representation."

It also means that you if you have a function like:

void some_func(struct X * x);

You can pass your union object with something like:

union U u;
some_func(&u.x);

Eric Sosman

5/28/2011 1:59:00 AM

0

On 5/27/2011 4:58 PM, Edward Rutherford wrote:
> If I have an union
>
> union U {
> struct X x;
> struct Y y;
> struct Z z;
>
> } u;
>
> and both struct Y and struct Z have a struct X as the first field, then
> can I always access u.x.<field> even if I am actually putting a struct Y
> or Z in u?

Yes, for any practical implementation. But according to the
letter of the law (as I read it), no.

There is a special dispensation (6.5.2.3p5) for unions of
structs that share a "common initial sequence" of elements. If
`struct X' were `short shrift; double trouble; char broiled;' and
`struct Y' were `short shrift; double trouble; long john_silver;',
then you could access the `shrift' and `trouble' members of either,
no matter which had been most recently stored in the union.

*But* your union isn't like that. Your `struct Y' actually looks
like `struct X marks_the_spot; long john_silver;', and so does not
share a "common initial sequence" with `struct X'. X's first element
is a `short', Y's is a `struct X', `short' and `struct X' are not
compatible types, so there's no "common initial sequence."

You could regain compatibility by "expanding" the `struct X'
in `struct Y', listing its elements explicitly rather than lumping
them together as a `struct X' instance. That is, if `struct Y' were
`short snort; double down; long john_silver;' all would be well.

... as it almost certainly will be anyhow, on any practical
implementation. The objection I raise is an incredibly nit-picky,
angels-on-pinheads kind of argument that no practical programmer
would pay attention to -- until the optimizer bit his behind. And
it's possible I'm misinterpreting "corresponding members." This
may be a question for the kilobuck-an-hour language lawyers.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Joe Pfeiffer

5/28/2011 3:13:00 AM

0

Eric Sosman <esosman@ieee-dot-org.invalid> writes:

> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
>> If I have an union
>>
>> union U {
>> struct X x;
>> struct Y y;
>> struct Z z;
>>
>> } u;
>>
>> and both struct Y and struct Z have a struct X as the first field, then
>> can I always access u.x.<field> even if I am actually putting a struct Y
>> or Z in u?
>
> Yes, for any practical implementation. But according to the
> letter of the law (as I read it), no.
>
> There is a special dispensation (6.5.2.3p5) for unions of
> structs that share a "common initial sequence" of elements. If
> `struct X' were `short shrift; double trouble; char broiled;' and
> `struct Y' were `short shrift; double trouble; long john_silver;',
> then you could access the `shrift' and `trouble' members of either,
> no matter which had been most recently stored in the union.
>
> *But* your union isn't like that. Your `struct Y' actually looks
> like `struct X marks_the_spot; long john_silver;', and so does not
> share a "common initial sequence" with `struct X'. X's first element
> is a `short', Y's is a `struct X', `short' and `struct X' are not
> compatible types, so there's no "common initial sequence."
>
> You could regain compatibility by "expanding" the `struct X'
> in `struct Y', listing its elements explicitly rather than lumping
> them together as a `struct X' instance. That is, if `struct Y' were
> `short snort; double down; long john_silver;' all would be well.
>
> ... as it almost certainly will be anyhow, on any practical
> implementation. The objection I raise is an incredibly nit-picky,
> angels-on-pinheads kind of argument that no practical programmer
> would pay attention to -- until the optimizer bit his behind. And
> it's possible I'm misinterpreting "corresponding members." This
> may be a question for the kilobuck-an-hour language lawyers.

This is totally irrelevant to the actual content of your post, but I'm
in awe of your examples. Casually stringing together a series of puns
like that to really good purpose is just amazing.
--
"Erwin, do you know what happened to the cat?" -- Mrs. Shroedinger

luserXtrog

5/28/2011 8:04:00 AM

0

Joe Pfeiffer wrote:
> Eric Sosman <esosman@ieee-dot-org.invalid> writes:
>
> > On 5/27/2011 4:58 PM, Edward Rutherford wrote:
> >> If I have an union

..OT
Is this (english) usage common? It rings funny in my middle-american
ears.
The long "u" begins with a 'yi' sound that serves as a consonant.
..\OT

> >>
> >> union U {
> >> struct X x;
> >> struct Y y;
> >> struct Z z;
> >>
> >> } u;
> >>
> >> and both struct Y and struct Z have a struct X as the first field, then
> >> can I always access u.x.<field> even if I am actually putting a struct Y
> >> or Z in u?
> >
> > Yes, for any practical implementation. But according to the
> > letter of the law (as I read it), no.
> >
> > There is a special dispensation (6.5.2.3p5) for unions of
> > structs that share a "common initial sequence" of elements.

Shouldn't it work on the level of 'elementary' elements?
Ie. down to the raw types.

> > If
> > `struct X' were `short shrift; double trouble; char broiled;' and
> > `struct Y' were `short shrift; double trouble; long john_silver;',
> > then you could access the `shrift' and `trouble' members of either,
> > no matter which had been most recently stored in the union.
> >
> > *But* your union isn't like that. Your `struct Y' actually looks
> > like `struct X marks_the_spot; long john_silver;', and so does not
> > share a "common initial sequence" with `struct X'. X's first element
> > is a `short', Y's is a `struct X', `short' and `struct X' are not
> > compatible types, so there's no "common initial sequence."
> >
> > You could regain compatibility by "expanding" the `struct X'
> > in `struct Y', listing its elements explicitly rather than lumping
> > them together as a `struct X' instance. That is, if `struct Y' were
> > `short snort; double down; long john_silver;' all would be well.
> >
> > ... as it almost certainly will be anyhow, on any practical
> > implementation. The objection I raise is an incredibly nit-picky,
> > angels-on-pinheads kind of argument that no practical programmer
> > would pay attention to -- until the optimizer bit his behind. And
> > it's possible I'm misinterpreting "corresponding members." This
> > may be a question for the kilobuck-an-hour language lawyers.
>
> This is totally irrelevant to the actual content of your post, but I'm
> in awe of your examples. Casually stringing together a series of puns
> like that to really good purpose is just amazing.

Ditto. Pedogogical gold.

luser-d

> --
> "Erwin, do you know what happened to the cat?" -- Mrs. Shroedinger

"It cannot be known; but I can find out!"

Ian Collins

5/28/2011 8:13:00 AM

0

On 05/28/11 08:03 PM, luser- -droog wrote:
> Joe Pfeiffer wrote:
>> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
>>
>>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
>>>> If I have an union
>
> ..OT
> Is this (english) usage common? It rings funny in my middle-american
> ears.
> The long "u" begins with a 'yi' sound that serves as a consonant.

No, words starting with a u that is sounded like a y (as in you) are
exceptions to the an before a vowel rule.

> ..\OT

--
Ian Collins

Willem

5/28/2011 8:42:00 AM

0

Ian Collins wrote:
) On 05/28/11 08:03 PM, luser- -droog wrote:
)> Joe Pfeiffer wrote:
)>> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
)>>
)>>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
)>>>> If I have an union
)>
)> ..OT
)> Is this (english) usage common? It rings funny in my middle-american
)> ears.
)> The long "u" begins with a 'yi' sound that serves as a consonant.
)
) No, words starting with a u that is sounded like a y (as in you) are
) exceptions to the an before a vowel rule.

However, "an union" is perfectly correct if you're referring
to the multi-layered vegetable.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Eric Sosman

5/28/2011 1:50:00 PM

0

On 5/28/2011 4:03 AM, luser- -droog wrote:
> Joe Pfeiffer wrote:
>> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
>>
>>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
>>>> If I have an union
>
> .OT
> Is this (english) usage common? It rings funny in my middle-american
> ears.
> The long "u" begins with a 'yi' sound that serves as a consonant.
> .\OT
>
>>>>
>>>> union U {
>>>> struct X x;
>>>> struct Y y;
>>>> struct Z z;
>>>>
>>>> } u;
>>>>
>>>> and both struct Y and struct Z have a struct X as the first field, then
>>>> can I always access u.x.<field> even if I am actually putting a struct Y
>>>> or Z in u?
>>>
>>> Yes, for any practical implementation. But according to the
>>> letter of the law (as I read it), no.
>>>
>>> There is a special dispensation (6.5.2.3p5) for unions of
>>> structs that share a "common initial sequence" of elements.
>
> Shouldn't it work on the level of 'elementary' elements?
> Ie. down to the raw types.

Padding could be a problem. Let's take a concrete example:

struct X {
double trouble;
char broiled;
};

struct Y {
double trouble;
char broiled;
short snort;
};

struct Z {
struct X marks_the_spot;
short snort;
};

union Pacific{ // just so 6.5.2.3p5 applies
struct X x;
struct Y y;
struct Z z;
};

On many machines, you are likely to find that sizeof(struct Z)
is greater than sizeof(struct Y), and offsetof(struct Z, snort)
is unequal to offsetof(struct Y, snort). So even though struct Y
and struct Z begin with the same sequence of elementary members,
they nonetheless do not share a "common initial sequence" and do
not have the same layout.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Joe Wright

5/28/2011 2:58:00 PM

0

On 5/28/2011 04:42, Willem wrote:
> Ian Collins wrote:
> ) On 05/28/11 08:03 PM, luser- -droog wrote:
> )> Joe Pfeiffer wrote:
> )>> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
> )>>
> )>>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
> )>>>> If I have an union
> )>
> )> ..OT
> )> Is this (english) usage common? It rings funny in my middle-american
> )> ears.
> )> The long "u" begins with a 'yi' sound that serves as a consonant.
> )
> ) No, words starting with a u that is sounded like a y (as in you) are
> ) exceptions to the an before a vowel rule.
>
> However, "an union" is perfectly correct if you're referring
> to the multi-layered vegetable.

Of course that would be "an onion". I believe "a union" correct.

--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."

Joe Pfeiffer

5/28/2011 2:59:00 PM

0

Willem <willem@toad.stack.nl> writes:

> Ian Collins wrote:
> ) On 05/28/11 08:03 PM, luser- -droog wrote:
> )> Joe Pfeiffer wrote:
> )>> Eric Sosman<esosman@ieee-dot-org.invalid> writes:
> )>>
> )>>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
> )>>>> If I have an union
> )>
> )> ..OT
> )> Is this (english) usage common? It rings funny in my middle-american
> )> ears.
> )> The long "u" begins with a 'yi' sound that serves as a consonant.
> )
> ) No, words starting with a u that is sounded like a y (as in you) are
> ) exceptions to the an before a vowel rule.
>
> However, "an union" is perfectly correct if you're referring
> to the multi-layered vegetable.

The mis-spelled multi-layered vegetable, at any rate.
--
"Erwin, do you know what happened to the cat?" -- Mrs. Shroedinger

luserXtrog

5/29/2011 7:41:00 AM

0

On May 28, 8:49 am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 5/28/2011 4:03 AM, luser- -droog wrote:
>
>
>
> > Joe Pfeiffer wrote:
> >> Eric Sosman<esos...@ieee-dot-org.invalid>  writes:
>
> >>> On 5/27/2011 4:58 PM, Edward Rutherford wrote:
> >>>> If I have an union
>
> > .OT
> > Is this (english) usage common? It rings funny in my middle-american
> > ears.
> > The long "u" begins with a 'yi' sound that serves as a consonant.
> > .\OT
>
> >>>> union U {
> >>>>       struct X x;
> >>>>       struct Y y;
> >>>>       struct Z z;
>
> >>>> } u;
>
> >>>> and both struct Y and struct Z have a struct X as the first field, then
> >>>> can I always access u.x.<field>   even if I am actually putting a struct Y
> >>>> or Z in u?
>
> >>>      Yes, for any practical implementation.  But according to the
> >>> letter of the law (as I read it), no.
>
> >>>      There is a special dispensation (6.5.2.3p5) for unions of
> >>> structs that share a "common initial sequence" of elements.
>
> > Shouldn't it work on the level of 'elementary' elements?
> > Ie. down to the raw types.
>
>      Padding could be a problem.  Let's take a concrete example:
>
>         struct X {
>             double trouble;
>             char broiled;
>         };
>
>         struct Y {
>             double trouble;
>             char broiled;
>             short snort;
>         };
>
>         struct Z {
>             struct X marks_the_spot;
>             short snort;
>         };
>
>         union Pacific{  // just so 6.5.2.3p5 applies
>             struct X x;
>             struct Y y;
>             struct Z z;
>         };
>
> On many machines, you are likely to find that sizeof(struct Z)
> is greater than sizeof(struct Y), and offsetof(struct Z, snort)
> is unequal to offsetof(struct Y, snort).  So even though struct Y
> and struct Z begin with the same sequence of elementary members,
> they nonetheless do not share a "common initial sequence" and do
> not have the same layout.

Understood, but trouble and broiled should be ok, right? ie.
accessible
through all the union members having assigned through any one of them.