union member

I

irwishlaw

After compiling and running the following program

#include <stdio.h>
#include <string.h>

typedef union
{
int a;
char b[2048];
float c;
} Foo, *LPFOO;

static Foo Bloof;

int main(int argc, char *argv[])
{
Bloof.a=1;
printf("% d\n",(int)Bloof.a);
strcpy(Bloof.b,"Hello, World!");
printf("%s\n",Bloof.b);
printf("% d\n",(int)Bloof.a);
Bloof.c=3.14159;
printf("% .7G\n",(float)Bloof.c);
return 0;
}

the results produced are

1
Hello, World!
1819043144
3.14159

After Bloof.b has been made the active member of the union
what is the nature of the value, 1819043144, that the

printf("% d\n",(int)Bloof.a);

produces? Is it a numerical value related to the value, "Hello
World",
of the active union member Bloof.b or an address or just a random
number?

Robert Wishlaw
 
J

Joachim Schmitz

After compiling and running the following program

#include <stdio.h>
#include <string.h>

typedef union
{
int a;
char b[2048];
float c;
} Foo, *LPFOO;

static Foo Bloof;

int main(int argc, char *argv[])
{
Bloof.a=1;
printf("% d\n",(int)Bloof.a);
strcpy(Bloof.b,"Hello, World!");
printf("%s\n",Bloof.b);
printf("% d\n",(int)Bloof.a);
Bloof.c=3.14159;
printf("% .7G\n",(float)Bloof.c);
return 0;
}

the results produced are

1
Hello, World!
1819043144
3.14159

After Bloof.b has been made the active member of the union
what is the nature of the value, 1819043144, that the

printf("% d\n",(int)Bloof.a);

produces? Is it a numerical value related to the value, "Hello
World",
of the active union member Bloof.b or an address or just a random
number?
1819043144 == 0x6C6C6548, interpreted as ASCII it is "lleH", on an little
endian machine that would be the beginning of your string "Hello, World".
So apparently it is not purely random, but probaly undefined behavoir.

Bye, Jojo
 
D

Drew Lawson

After compiling and running the following program

#include <stdio.h>
#include <string.h>

typedef union
{
int a;
char b[2048];
float c;
} Foo, *LPFOO;
[snip]

After Bloof.b has been made the active member of the union
what is the nature of the value, 1819043144, that the

There is no "active member" of a union. A union is a way to overlay
multiple uses on the same memory, but it does not track which use
you have used most recently. On the few instances that I need/use
a union for that sort of thing, I include it in a wrapper struct
with another field indicating what's in the union.

To be honest, the last time I recall using a union in professional
code was on a project that was started in 1994.
 
B

Ben Pfaff

There is no "active member" of a union.

The C standard does not use that exact term, but it does talk
about how the member of a union last stored into is the only
member whose value is not unspecified. One could reasonably
regard that member to be the "active member":

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.
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.
 
K

Kenneth Brody

Ben said:
(e-mail address removed) (Drew Lawson) writes: [...]
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.

Yes, I suppose it could if it really wanted to, by doing the equivalent
of turning the union into a struct consisting of the union plus a
tracker, and setting the tracker on every assignment to the union,
and checking the tracker on every reference to the union. However,
what would you expect the implementation do if it detected a mismatch?

On the other hand, I seem to recall that are allowed to access the
union via an array of unsigned chars, even if that was not the last
assignment. For example:

union examine_double_format
{
double value;
unsigned char bytes[sizeof(double)];
};

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
B

Ben Pfaff

Kenneth Brody said:
Ben said:
(e-mail address removed) (Drew Lawson) writes: [...]
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.

Yes, I suppose it could if it really wanted to, by doing the equivalent
of turning the union into a struct consisting of the union plus a
tracker, and setting the tracker on every assignment to the union,
and checking the tracker on every reference to the union. However,
what would you expect the implementation do if it detected a mismatch?

Provide a diagnostic to the programmer, who could then fix the
bug? It would be great if programming tools could report this
sort of standard violation.
On the other hand, I seem to recall that are allowed to access the
union via an array of unsigned chars, even if that was not the last
assignment. [...]

Yes, there are some special exceptions to the rule.
 
E

Eric Sosman

Kenneth Brody wrote On 04/25/07 14:13,:
Ben said:
(e-mail address removed) (Drew Lawson) writes:
[...]
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.


Yes, I suppose it could if it really wanted to, by doing the equivalent
of turning the union into a struct consisting of the union plus a
tracker, and setting the tracker on every assignment to the union,
and checking the tracker on every reference to the union. [...]

I think that could produce false positives:

union { int i; double d; } u;
u.i = 42; /* tracker says "int" */
sscanf("42.42", "%lf", &u.d);
printf ("%f\n", u.d); /* tracker mismatch? */

The assignment to u.d takes place inside sscanf(), where
it's not known that the pointer is to a union member as
opposed to a free-standing double.
 
K

Keith Thompson

Ben Pfaff said:
Kenneth Brody said:
Ben said:
(e-mail address removed) (Drew Lawson) writes: [...]
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.

Yes, I suppose it could if it really wanted to, by doing the equivalent
of turning the union into a struct consisting of the union plus a
tracker, and setting the tracker on every assignment to the union,
and checking the tracker on every reference to the union. However,
what would you expect the implementation do if it detected a mismatch?

Provide a diagnostic to the programmer, who could then fix the
bug? It would be great if programming tools could report this
sort of standard violation.

Providing a diagnostic *to the programmer* implies a compile-time
message, which isn't always possible. Where it is possible, compilers
can already do it without adding a tracker to the union itself (or
rather by implementing the tracker within the compiler).

Detecting it at run time would be tricky, assuming you want to
maintain compatibility. I suppose you could store the tracker in what
would otherwise be padding bytes at the end of the union (you can't
put it at the beginning because the explicit members all have to have
an offset of 0).

That leaves the question of what to do if you detect an error at run
time. You could just abort the program, which is what often happens
for things like null pointer dereferences. Or you could raise a
signal.

Then again, if a programmer wants to use something like what Pascal
calls a variant record, he can implement it himself.
 
B

Ben Pfaff

Keith Thompson said:
Ben Pfaff said:
Kenneth Brody said:
Ben Pfaff wrote:
(e-mail address removed) (Drew Lawson) writes:
[...]
A union is a way to overlay multiple uses on the same memory,
but it does not track which use you have used most recently.

I don't see why the implementation could not do so; it's simply
that normal implementations do not.

Yes, I suppose it could if it really wanted to, by doing the equivalent
of turning the union into a struct consisting of the union plus a
tracker, and setting the tracker on every assignment to the union,
and checking the tracker on every reference to the union. However,
what would you expect the implementation do if it detected a mismatch?

Provide a diagnostic to the programmer, who could then fix the
bug? It would be great if programming tools could report this
sort of standard violation.

Detecting it at run time would be tricky, assuming you want to
maintain compatibility. I suppose you could store the tracker in what
would otherwise be padding bytes at the end of the union (you can't
put it at the beginning because the explicit members all have to have
an offset of 0).

I was thinking of a mechanism like the one that Valgrind uses to
track memory initialization state; that is, data completely in an
address space logically separate from that accessible by the
program.

Not every implementation has to be one useful for running
programs at a practical speed; I'm happy to do some testing of my
software under implementations that run with 100X overhead, if
they find important bugs.
 

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


Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top