About Union's question

  • Thread starter =?gb2312?B?zfWzrLey?=
  • Start date
G

Guest

Jack said:
Marcin said:
Union un
{ int I;
char c[2];
}


After "fixing" your code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

so, after union is created it is filled with trash. Then you assign a
values
but only to "char" components, the other two bytes of "int" component are
still filled with "trash". So final answer is "you will get unspecified
number".
Ah, yes, I missed that these other bytes still may be uninitialized... (on
an implementation with sizeof(int) != 2)

but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);

would still give some implementation/architecture dependant output.

No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.

The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even if it
weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
 
C

CBFalconer

Harald said:
Jack said:
.... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);

would still give some implementation/architecture dependant output.

No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.

The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.

No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.
 
R

Robert Gamble

... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.

No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.

Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?

Robert Gamble
 
L

Lew Pitcher

... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.

Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?

I believe that Chuck is referring to ISO/IEC 9899:1999 (draft)
6.7.2.1.14, where it says
14 The size of a union is sufï¬cient to contain the largest of its
members. The value of at
most one of the members can be stored in a union object at any
time. A pointer to a
union object, suitably converted, points to each of its members
(or if a member is a bit-
ï¬eld, then to the unit in which it resides), and vice versa.

The key being the second sentence. The code posted above populates a
value into one member of the union, and subsequently references a
different member of the union without that subsequent member having
been populated. The "undefined behaviour" is the behaviour of the code
when the alternate member is referenced. About this behaviour, the
standard sayeth not.
 
L

Lew Pitcher

Harald van D?k wrote:
Jack Klein wrote:
... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.
Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?

I believe that Chuck is referring to ISO/IEC 9899:1999 (draft)
6.7.2.1.14, where it says
14 The size of a union is sufï¬cient to contain the largest of its
members. The value of at
most one of the members can be stored in a union object at any
time. A pointer to a
union object, suitably converted, points to each of its members
(or if a member is a bit-
ï¬eld, then to the unit in which it resides), and vice versa.

The key being the second sentence. The code posted above populates a
value into one member of the union, and subsequently references a
different member of the union without that subsequent member having
been populated. The "undefined behaviour" is the behaviour of the code
when the alternate member is referenced. About this behaviour, the
standard sayeth not.

For that matter, ISO/IEC 9899:1999 (draft) J.1 says (wrt "Unspecified
Behaviour")
"The following are unspecified
...
— The value of a union member other than the last one stored into
(6.2.6.1).
"
 
R

Robert Gamble

Harald van D?k wrote:
Jack Klein wrote:
... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.
Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?

I believe that Chuck is referring to ISO/IEC 9899:1999 (draft)
6.7.2.1.14, where it says
14 The size of a union is sufï¬cient to contain the largest of its
members. The value of at
most one of the members can be stored in a union object at any
time. A pointer to a
union object, suitably converted, points to each of its members
(or if a member is a bit-
ï¬eld, then to the unit in which it resides), and vice versa.

The key being the second sentence. The code posted above populates a
value into one member of the union, and subsequently references a
different member of the union without that subsequent member having
been populated. The "undefined behaviour" is the behaviour of the code
when the alternate member is referenced. About this behaviour, the
standard sayeth not.

I think that sentence is simply pointing out the fact that since the
members overlap it is not possible to have multiple members stored at
the same time. The standard makes it clear that any object can be
accessed through unsigned char without invoking UB, this includes when
a non-char member of a union is stored and then accessed via an
unsigned char member of that union. This is always safe because
unsigned char is specified as having no trap representations.
Furthermore, DR 283 adds a footnote to 6.5.2.3#3 which reads:

"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."

This sentence would be pointless if such access was undefined
behavior. The undefined behavior comes from the fact that the
resulting representation may be a trap representation, if it is not
then there is no undefined behavior.

Robert Gamble
 
R

Robert Gamble

Harald van D?k wrote:
Jack Klein wrote:
... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.
Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?
I believe that Chuck is referring to ISO/IEC 9899:1999 (draft)
6.7.2.1.14, where it says
14 The size of a union is sufï¬cient to contain the largest of its
members. The value of at
most one of the members can be stored in a union object at any
time. A pointer to a
union object, suitably converted, points to each of its members
(or if a member is a bit-
ï¬eld, then to the unit in which it resides), and vice versa.
The key being the second sentence. The code posted above populates a
value into one member of the union, and subsequently references a
different member of the union without that subsequent member having
been populated. The "undefined behaviour" is the behaviour of the code
when the alternate member is referenced. About this behaviour, the
standard sayeth not.

For that matter, ISO/IEC 9899:1999 (draft) J.1 says (wrt "Unspecified
Behaviour")
"The following are unspecified
...
— The value of a union member other than the last one stored into
(6.2.6.1).
"

This is a defect in the Standard, one that frustratingly causes more
confusion than any other I can think of at the moment. This is left
over from a previous Standard version, there is no supporting text for
this statement in the Standard proper. Someone should really submit a
DR for this.

Robert Gamble
 
G

Guest

Lew said:
Harald van D?k wrote:
Jack Klein wrote:
"Joachim Schmitz" <[email protected]> wrote:
... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.

Can you provide the C&V that supports your claim of undefined behavior
given the no trap representation provision?

I believe that Chuck is referring to ISO/IEC 9899:1999 (draft)
6.7.2.1.14, where it says
14 The size of a union is sufï¬cient to contain the largest of its
members. The value of at
most one of the members can be stored in a union object at any
time. A pointer to a
union object, suitably converted, points to each of its members
(or if a member is a bit-
ï¬eld, then to the unit in which it resides), and vice versa.

The key being the second sentence. The code posted above populates a
value into one member of the union, and subsequently references a
different member of the union without that subsequent member having
been populated. The "undefined behaviour" is the behaviour of the code
when the alternate member is referenced. About this behaviour, the
standard sayeth not.

The standard says that the value of at most one of the members can be
stored, but does not say that reading a different member produces
undefined behaviour. Since it doesn't, and since the code doesn't
violate the aliasing rules, reading a different member is covered by
all the usual rules.
 
C

CBFalconer

Robert said:
CBFalconer said:
Harald said:
Jack Klein wrote:
"Joachim Schmitz" <[email protected]> wrote:

... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.

No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.

Can you provide the C&V that supports your claim of undefined
behavior given the no trap representation provision?

6.2.6.1:
... snip ...

[#7] When a value is stored in a member of an object of
union type, the bytes of the object representation that do
not correspond to that member but do correspond to other
members take unspecified values, but the value of the union
object shall not thereby become a trap representation.

... snip ...

6.5.2.3 Structure and union members

Constraints

.... snip ...

[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.70) One special guarantee is made in
order to simplify the use of unions: If a union contains
several structures that share a common initial sequence (see
below), and if the union object currently contains one of
these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of
the completed type of the union is visible. Two structures
share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths)
for a sequence of one or more initial members.
 
R

Robert Gamble

Robert said:
CBFalconer said:
Harald van D?k wrote:
Jack Klein wrote:
... snip ...
but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);
would still give some implementation/architecture dependant output.
No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.
The program is guaranteed to print an unspecified value on
implementations where int has no trap representations, and even
if it weren't, the output (if any) would still be implementation/
architecture dependant. That's part of what "undefined" means.
No it isn't. The arguments are evaluated (and the undefined
behaviour occurs) _before_ the call to printf executes. It is
fairly hard to execute "call by value" without having the value
with which to call.
Can you provide the C&V that supports your claim of undefined
behavior given the no trap representation provision?

6.2.6.1:
... snip ...

[#7] When a value is stored in a member of an object of
union type, the bytes of the object representation that do
not correspond to that member but do correspond to other
members take unspecified values, but the value of the union
object shall not thereby become a trap representation.

Nothing about undefined behavior here...
... snip ...

6.5.2.3 Structure and union members

Constraints

... snip ...

[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.70)
[snip]

This sentence exists in a pre-C99 draft but not in the actual
Standard, there is a reason for that.

Robert Gamble
 
O

Old Wolf

union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);

The program is guaranteed to print an unspecified value on
implementations where int has no trap representations

In C89, it explicitly says that the behaviour is undefined if
you access a union member that was not the most recent one set.

In C99 this rule was relaxed and it does seem to be as you say,
with a pile of assumptions.
 
O

Old Wolf

Robert said:
Can you provide the C&V that supports your claim of undefined
behavior given the no trap representation provision?

6.2.6.1:
... snip ...

[#7] When a value is stored in a member of an object of
union type, the bytes of the object representation that do
not correspond to that member but do correspond to other
members take unspecified values, but the value of the union
object shall not thereby become a trap representation.

This is saying that the value of the union as a whole is
not a trap, i.e. you can pass it to functions and so on.
It doesn't say that there won't be a trap if any particular
member of the union is selected.
6.5.2.3 Structure and union members

[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.70)

This text is not in C99. I suggest that if you are to use N869
as a reference then you double check things with N1124 before
posting.
 
C

CBFalconer

Old said:
.... snip ...
6.5.2.3 Structure and union members

[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.70)

This text is not in C99. I suggest that if you are to use N869
as a reference then you double check things with N1124 before
posting.

Made a note. Hopefully I will get around to checking this and
possibly editing my copy of N869 later.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top