Union Issue

R

ranjeet.gupta

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

<--------------Unsigned int a------------------>
-----------------------------------------------
| | | | |
------------------------------------------------
<--b[0]--><---b[1]--->


int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

when i write the above code the it means that
<--------------Unsigned int a-------->
-------------------------------------
|00000000|00000000|00000010|0000000|
-------------------------------------
<--b[0]-><--b[1]->


Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

Regards
Ranjeet
 
M

Madhav

Its not the padding. when you print a string, it should be terminated
by an ascii null character. In your case , it may not have been there.
 
P

pete

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

The size of the union may be larger than it's largest data type.
Try char b[5]; instead of char b[2];
and then read sizeof d.
what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};
int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

The purpose of unions is not to read a
different type than the one last written.

N869
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. 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.
 
K

Keith Thompson

Madhav said:
Its not the padding. when you print a string, it should be terminated
by an ascii null character. In your case , it may not have been there.

Please provide some context when you post a followup. Don't assume
that everyone can see the parent article.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

In any case, the problem in the original article has nothing to do
with string termination.
 
R

ranjeet.gupta

pete said:
Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

The size of the union may be larger than it's largest data type.
Try char b[5]; instead of char b[2];
and then read sizeof d.
what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};
int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

The purpose of unions is not to read a
different type than the one last written.

Yes it may what u said is correct, That the purpose of unions is
not to read the type than the one last written, As far as what
I understood is that when we initialse the on data type then
by the garce of the union defination in "C" we can access the
values of the diffrent data types, This leads to the intraction
through the diffrent hardware. Is this not a way to achive the
interaction with the diffrent hardwares ? Or I am on wrong path.


N869
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. 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.
 
P

pete

Is this not a way to achive the
interaction with the diffrent hardwares ? Or I am on wrong path.

You can inspect the bytes of an object this way:

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
long unsigned number, bytes;

number = 0x12345678;
printf("\nnumber is 0x%lx\n\n", number);
for (bytes = 0; bytes != sizeof number; ++bytes) {
printf("byte %lu is 0x%x\n",
bytes, (unsigned)((unsigned char *)&number)[bytes]);
}
return 0;
}

/* END new.c */
 
K

Keith Thompson

As we know that when we declare the union then we have the size of
the union which is the size of the highest data type as in the below
case the size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
}; [...]
int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
[...]

Ok, we're assuming sizeof(unsigned int) is 4.
Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

A couple of things you should fix, even though they aren't actually
causing any problems:

"int main()" should be "int main(void)". Both are valid, but the
latter is better style.

You need to to add "#include <stdio.h>". Without this, calling
printf() invokes undefined behavior (though it typically happens to
work anyway).

Use "%u", not "%d", to print an unsigned int.

Now on to the actual issue.

d.b is an array of 2 chars. You're allowed to refer to d.b[0] and
d.b[1]. Attempting to refer to any other array elements invokes
undefined behavior. In your case, that happens to show up as
accessing bytes of d.a (the unsigned int), but you shouldn't count on
it.

(Actually, since there are special rules about aliasing objects as
character arrays, it could probably be argued that the behavior is
defined, but it's still not a good idea to depend on it.)

In any case, you certainly can't depend on the compiler to catch the
error of indexing past the end of an array. It's up to you to avoid
it.
 
J

junky_fellow

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

<--------------Unsigned int a------------------>
-----------------------------------------------
| | | | |
------------------------------------------------
<--b[0]--><---b[1]--->


int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

when i write the above code the it means that
<--------------Unsigned int a-------->
-------------------------------------
|00000000|00000000|00000010|0000000|
-------------------------------------
<--b[0]-><--b[1]->


Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

Regards
Ranjeet

<OT>
My answer is not at all related to satndard C. Just to give you a
hint of what might be happening.
I think you are getting this result due to endianness of the processor.
And in your case your processor should be little endian.
d.a = 512 * 512 = 0x00040000 (assuming unsigned int 4 bytes )
If your processor is little endian, 0x40000 (I believe it is unsigned
int as declared in your union) will be stored as
lowest address byte of integer ----> 00 00 04 00

So, if you access this object as (char *) and print the bytes one
by one in sequential increasing order, the output will be
0,0,4,0.

</OT>
 
R

ranjeet.gupta

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

<--------------Unsigned int a------------------>
-----------------------------------------------
| | | | |
------------------------------------------------
<--b[0]--><---b[1]--->


int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

when i write the above code the it means that
<--------------Unsigned int a-------->
-------------------------------------
|00000000|00000000|00000010|0000000|
-------------------------------------
<--b[0]-><--b[1]->


Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

Regards
Ranjeet

<OT>
My answer is not at all related to satndard C. Just to give you a
hint of what might be happening.
I think you are getting this result due to endianness of the processor.
And in your case your processor should be little endian.
d.a = 512 * 512 = 0x00040000 (assuming unsigned int 4 bytes )
If your processor is little endian, 0x40000 (I believe it is unsigned
int as declared in your union) will be stored as
lowest address byte of integer ----> 00 00 04 00

So, if you access this object as (char *) and print the bytes one
by one in sequential increasing order, the output will be
0,0,4,0.

Thats correct what u said and yes my processor is Little endian
this is what it will do, But as in union I have defined the
char[2], Means only two bytes, But I am able to get the value
of char[2] and and char[3], This I am not able to undersand
why i am geting this abnormal behaviour as I have only declared
2 bytes not 4 bytes of Char in the union
 
J

junky_fellow

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

<--------------Unsigned int a------------------>
-----------------------------------------------
| | | | |
------------------------------------------------
<--b[0]--><---b[1]--->


int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

when i write the above code the it means that
<--------------Unsigned int a-------->
-------------------------------------
|00000000|00000000|00000010|0000000|
-------------------------------------
<--b[0]-><--b[1]->


Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

Regards
Ranjeet

<OT>
My answer is not at all related to satndard C. Just to give you a
hint of what might be happening.
I think you are getting this result due to endianness of the processor.
And in your case your processor should be little endian.
d.a = 512 * 512 = 0x00040000 (assuming unsigned int 4 bytes )
If your processor is little endian, 0x40000 (I believe it is unsigned
int as declared in your union) will be stored as
lowest address byte of integer ----> 00 00 04 00

So, if you access this object as (char *) and print the bytes one
by one in sequential increasing order, the output will be
0,0,4,0.

Thats correct what u said and yes my processor is Little endian
this is what it will do, But as in union I have defined the
char[2], Means only two bytes, But I am able to get the value
of char[2] and and char[3], This I am not able to undersand
why i am geting this abnormal behaviour as I have only declared
2 bytes not 4 bytes of Char in the union

This is because when you declared union "d" of type "data_type", the
memory
allocated will be (Assuming sizeof char to be 1 byte and sizeof int
to be 4 bytes on your machine) 4 bytes.

When you access b[2], it will be expanded as *((char *)b + 2 ).
So, it will try to access the third byte of the union d, which is a
valid
address.
 
R

ranjeet.gupta

(e-mail address removed) wrote:
Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

<--------------Unsigned int a------------------>
-----------------------------------------------
| | | | |
------------------------------------------------
<--b[0]--><---b[1]--->


int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

when i write the above code the it means that
<--------------Unsigned int a-------->
-------------------------------------
|00000000|00000000|00000010|0000000|
-------------------------------------
<--b[0]-><--b[1]->


Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]
Is the internal padding for the char is also going on in union.
thats is making to the 4 bytes char, Does Union also support the
padding ? (Padding is implementation use)

Please let me know what is happening and what I understood wrong ?

Regards
Ranjeet

<OT>
My answer is not at all related to satndard C. Just to give you a
hint of what might be happening.
I think you are getting this result due to endianness of the processor.
And in your case your processor should be little endian.
d.a = 512 * 512 = 0x00040000 (assuming unsigned int 4 bytes )
If your processor is little endian, 0x40000 (I believe it is unsigned
int as declared in your union) will be stored as
lowest address byte of integer ----> 00 00 04 00

So, if you access this object as (char *) and print the bytes one
by one in sequential increasing order, the output will be
0,0,4,0.

Thats correct what u said and yes my processor is Little endian
this is what it will do, But as in union I have defined the
char[2], Means only two bytes, But I am able to get the value
of char[2] and and char[3], This I am not able to undersand
why i am geting this abnormal behaviour as I have only declared
2 bytes not 4 bytes of Char in the union

This is because when you declared union "d" of type "data_type", the
memory
allocated will be (Assuming sizeof char to be 1 byte and sizeof int
to be 4 bytes on your machine) 4 bytes.

When you access b[2], it will be expanded as *((char *)b + 2 ).
So, it will try to access the third byte of the union d, which is a
valid
address.

Thanks Junky I got it, As I was not sure about the above statement
and you made me some what assure. So it measn that we can access
the values to the highest size of any data member, (If highets
data member in out case is int) by any other data type which
we can derefrnece itself (arrays) as in my case i have declared in
the union, shuch as char[2], Now this will not be true for othere
data type which is not in the form of array, such as if i declare
as char b,
 
C

CBFalconer

pete said:
.... snip ...
what I conclude from the below code

union data_type {
unsigned int a;
char b[2];
};
int main ()
{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,
then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.

In fact there is no b[0] nor b[1] when he uses them.
 
T

Tim Rentsch

CBFalconer said:
pete said:
... snip ...
what I conclude from the below code

union data_type {
unsigned int a;
char b[2];
};
int main ()
{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,
then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.

In fact there is no b[0] nor b[1] when he uses them.

Consider the following:

union {
unsigned int a; /* and sizeof(unsigned int) == 4 */
char b[2];
} u;
char a, b, *p;

u.a = 0;

p = (void*) &u; a = p[1], b = p[3]; /* 1a, 1b */
p = (char*) &u; a = p[1], b = p[3]; /* 2a, 2b */
p = (void*) u.b; a = p[1], b = p[3]; /* 3a, 3b */
p = (char*) u.b; a = p[1], b = p[3]; /* 4a, 4b */
p = u.b; a = p[1], b = p[3]; /* 5a, 5b */
a = u.b[1], b = u.b[3]; /* 6a, 6b */


Do you believe that accesses 1a, 1b are allowed? I believe they are.

If so, where in the standard is there language that disallows the
accesses 6a, 6b, but allows the accesses 1a, 1b? At what point in the
sequence do the accesses change from allowed to disallowed?
 
T

Tim Rentsch

pete said:
Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

The size of the union may be larger than it's largest data type.
Try char b[5]; instead of char b[2];
and then read sizeof d.
what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};
int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.

When b[2] is an array of 'char', this might not be right. Please
see my response to CBF's followup.

The purpose of unions is not to read a
different type than the one last written.

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

FYI, this section was changed between N869 and the released standard.
The first sentence (saying that "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 ...") was removed. What's left is 6.2.6.1 p7

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.

Read that paragraph carefully, it says more than a casual reading
might suggest. In particular, if a value is stored into the largest
member of the union, the values of bytes of the other members are not
unspecified (except, eg, structure assignment might leave some bytes
unspecified because they are padding bytes). And assignment into part
of a member (for example an element of an array member or a field of a
struct member) doesn't affect the other parts of that member (that is,
not any more than it usually would, eg, bit field assignment).
 
P

pete

Tim said:
pete said:
Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

The size of the union may be larger than it's largest data type.
Try char b[5]; instead of char b[2];
and then read sizeof d.
what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};
int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}
Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.

When b[2] is an array of 'char', this might not be right. Please
see my response to CBF's followup.
The purpose of unions is not to read a
different type than the one last written.

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

FYI, this section was changed between N869 and the released standard.
The first sentence (saying that "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 ...") was removed. What's left is 6.2.6.1 p7

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.

Read that paragraph carefully, it says more than a casual reading
might suggest. In particular, if a value is stored into the largest
member of the union, the values of bytes of the other members are not
unspecified (except, eg, structure assignment might leave some bytes
unspecified because they are padding bytes). And assignment into part
of a member (for example an element of an array member or a field of a
struct member) doesn't affect the other parts of that member (that is,
not any more than it usually would, eg, bit field assignment).

No.
That paragraph doesn't say anything about the bytes that *do*
correspond to other members.

Paragraph 5 retains the "one special guarantee"

You're trying to say that it isn't special.
 
P

pete

pete said:
Tim said:
pete said:
(e-mail address removed) wrote:

Dear ALL

As we know that when we declare the union then we have the size of the
union which is the size of the highest data type as in the below case
the
size should be 4 (For my case and compiler), and it is,

The size of the union may be larger than it's largest data type.
Try char b[5]; instead of char b[2];
and then read sizeof d.

what I conclude from the below code

union data_type {

unsigned int a;
char b[2];
};

int main ()

{
union data_type d;
d.a = 512 * 512;
printf("%d\n", d.a);
printf("%d\n %d\n %d\n %d\n ", d.b[0],d.b[1],d.b[2],d.b[3]);
getchar();
return 0;
}

Now when I specificaaly Allcoate the char for two bytes array,

then why on fetching its is fetching the value of b[2] and b[3]

There is no b[2] and b[3]. Your code is undefined.

When b[2] is an array of 'char', this might not be right. Please
see my response to CBF's followup.
The purpose of unions is not to read a
different type than the one last written.

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

FYI, this section was changed between N869
and the released standard.
The first sentence (saying that "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 ...") was removed. What's left is 6.2.6.1 p7

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.

Read that paragraph carefully, it says more than a casual reading
might suggest. In particular, if a value is stored into the largest
member of the union, the values of bytes of the
other members are not
unspecified (except, eg, structure assignment might leave some bytes
unspecified because they are padding bytes).
And assignment into part
of a member (for example an element of an array
member or a field of a
struct member) doesn't affect the other parts of that member
(that is,
not any more than it usually would, eg, bit field assignment).

No.
That paragraph doesn't say anything about the bytes that *do*
correspond to other members.

Excuse me.
What I meant, is that it doesn't say anything about the bytes
that the members have in common.
 
T

Tim Rentsch

pete said:
Tim said:
pete said:
The purpose of unions is not to read a
different type than the one last written.

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

FYI, this section was changed between N869 and the released standard.
The first sentence (saying that "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 ...") was removed. What's left is 6.2.6.1 p7

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.

Read that paragraph carefully, it says more than a casual reading
might suggest. In particular, if a value is stored into the largest
member of the union, the values of bytes of the other members are not
unspecified (except, eg, structure assignment might leave some bytes
unspecified because they are padding bytes). And assignment into part
of a member (for example an element of an array member or a field of a
struct member) doesn't affect the other parts of that member (that is,
not any more than it usually would, eg, bit field assignment).

No.
That paragraph doesn't say anything about the bytes that *do*
correspond to other members.

You're right, the quoted paragraph doesn't say anything about bytes
that do correspond to other members (that the members have in common,
as you said in a later message). But it's still true that assigning
into part of one member doesn't change the values of other bytes of
that member. The guarantee of not changing other bytes (that still
lie within the union member being changed) derives from the semantics
of that assignment (eg, array element assignment or structure member
assignment) - since the element or structure member assignment doesn't
change other bytes of the union member it's affecting, those other
bytes can't change.

Paragraph 5 retains the "one special guarantee"

You're trying to say that it isn't special.

It's a sad day when making sense of the C standard requires trying to
divine the meaning of the undefined term "special".

What I said above doesn't depend on whether the guarantee in p5 is or
isn't special. A guarantee being special doesn't invalidate other
parts of the standard, and the statements above are guaranteed by
other parts of the standard.

Having said that, what makes the special guarantee special? This
paragraph imposes a weak form of (partial) type equivalence on certain
structure types. Without paragraph 5, an implementation could assume
that distinct (and disjoint) structure types could never be aliased;
with paragraph 5, that's not always possible. The guarantee is
special because it imposes further requirements on when expressions of
one type are explicitly permitted to refer to objects of a different
type. Other guarantees of type equivalence (6.2.5-7, etc) are
essentially unconditional - they hold all the time. Here we have a
limited type equivalence that holds only in certain circumstances;
hence, it is "special".
 
P

pete

Tim Rentsch wrote:
It's a sad day when making sense of the C standard requires trying to
divine the meaning of the undefined term "special".

In Australian Rules C, it's implementation defined.

ISO/IEC 9899: 1990
6.3.2.3 Structure and union members
With one exception,
if a member of a union object is accessed after a value
has been stored in a different member of the object,
the behavior is implementation-defined.
 
B

baumann@pan

hi i compiled the code below under redhat9

#include <stdio.h>
union data_type {


unsigned int a;
char b[2];



};

int main(void)
{
union data_type d;
d.a = 512*512;
printf("sizeof(d):%d\n",sizeof d);
printf("d.a:%#18x\n",d.a);
printf("&d:%p,&d.a:%p,&d.b:%p\n",&d,&d.a,&d.b);

printf("d.b[0]:%d,d.b[1]:%d,d.b[2]:%d,d.b[3]:%d\n",d.b[0],d.b[1],d.b[2],d.b[3]);
return 0;
}


and the output is

sizeof(d):4
d.a: 0x40000
&d:0xbfffe734,&d.a:0xbfffe734,&d.b:0xbfffe734
d.b[0]:0,d.b[1]:0,d.b[2]:4,d.b[3]:0
 

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

Similar Threads

C doubt- union 5
Union In C 4
Repeated types in union 18
union, strcpy and main() 10
Command Line Arguments 0
Adding adressing of IPv6 to program 1
Union and strict aliasing 4
Issue with textbox script? 0

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,208
Latest member
RandallLay

Latest Threads

Top