amit said:
Recall that in C, int and float are both 4 byte types. Consider the
following code.
[note that which version of The Standard you read will refine
some of these issues, to some extent]
This isn't necessarily true. In *some* implementations, int's
(unqualified -- i.e., not shorts or longs) are 4 bytes. In
*some* implementations, floats are 32 bits (IEEE 754-ish).
But, none of these are guaranteed. For example, a float
can be the same size as a double. And a double can be
the same size as a long double. I.e., a float can be
implemented AS IF it was a long double (8 bytes?).
Likewise, an int needs only be at least as large as a short int.
So, an int can be 2 bytes!
Having said this, just keep it in the back of your mind
as to how it further muddies the situation explained below...
(i.e., lets pretend your statement *is* true)
main()
{
float f, g;
union { float f; int i; } u;
srand48(time(0));
f = drand48();
u.f = f;
u.i++;
g = u.f;
// ===== POINT A ===== //
}
How about we write this simpler?
function()
{
float x, y;
union {
float f;
int i;
} u;
x = 3.1415926; /* some random floating point value */
u.f = x;
u.i = u.i + 1;
y = u.f;
// ===== POINT A ===== //
}
I.e., you are storing some "bit pattern" (depending on how
your compiler represents the floating point number 3.1415926)
in the "float" called x.
You are then *copying* that bit pattern into a float called
f that is located within a union called u. How this looks
in memory now not only depends on how the compiler chose to
represent that value, but, also, on how it arranges the storage
requirements for f *within* u!
You are then modifying some *portion* of the union using
access through some *other* object in that union (i.e., the i).
Then, you are reexamining the bit pattern from the original
means by which you accessed it (f).
Now, let's come up with a *similar* example:
function()
{
int x, y;
union {
float f;
int i;
} u;
x = 512; /* some random integer value */
u.i = x;
u.f = u.f + 1.0;
y = u.i;
// ===== POINT A ===== //
}
Note that this is essentially the same problem: storing
a bit pattern in a member of the union, modifying some
*other* member of that same union, then reexamining the
original member's "value". Right?
Now, a third example:
function()
{
int x, y;
union {
unsigned char a[4];
int i;
} u;
x = 27; /* some random integer */
u.i = x;
u.a[0] = u.a[0] + 1;
y = u.i;
// ===== POINT A ===== //
}
This is the same problem as the first two.
Now (guessing as to what you know of C), what do
you expect the results in the third example to be?
In what circumstances do your assumptions make sense?
[apologies if I've let some typos slip through]