question on union

M

Martin Ambuhl

Martin wrote:
[...]
The FAQ's reference is to an older
edition of H&S, so I don't know if that text was there. If that
text was there, Steve ought not to have suppressed it.
[...]

My copy of the book is dated 1996. I don't think there is a later
version.

You are wrong. H&S5 is from 2002.
In the book, as well as the union example I posted, there is also the
example as provided in the online FAQ, which uses a pointer. The
online FAQ and my edition of the book also cross-reference to Harbison
& Steel Sec. 6.1.2 pp. 163-4.

In H&S5 it is on p. 184
The introductory text you quote is not in my edition of the book.

It should have been.
 
D

dj3vande

[Implementing unions]
The mechanics don't matter. But one possible implementation is to
simply alias several distinct data type addresses to the same address
in memory, with a pointer for each desired type. In the real world,
it probably won't happen that way, since it would be wasteful. More
likely, there is a table in memory somewhere describing the layout for
each distinct union type. That table will have the different ways to
interpret the different members of the union recorded.

That table doesn't even have to exist at run time; as long as it's
maintained at compile time, the compiler can generate code that does
The Right Thing for the type of whatever member of the union it's
accessing, and once the code is generated there's no reason (other than
for debugging) to keep the type and layout information around.


dave
 
D

dj3vande

Then why do both values look differently, in debugger:

(gdb) p/x un
$3 = {s = 0x102, c = {0x2, 0x1}}
(gdb)

The value of something is determined by two things:
(1) the bit pattern of the memory it's stored in
(2) the type of the "something"
The type is important because it defines how the bit pattern is
interpreted.

With a union of two different objects of the same size (in your case a
short occupying two bytes and an array of two chars occupying one byte
each), the implementation will usually use the same memory for both
(the limitations on what you as a programmer can do with a union allow
it to do this, and this behavior is what most nonportable uses of a
union depend on), so the bit pattern of the memory is the same for both
objects (and happens to be valid for both in this case; knowing that it
will be usually requires some non-portable knowledge of the system it's
running on).

So since the actual data is the same, the type of the object you're
accessing the data through is what determines what it looks like.

When the debugger looks at un.s, it interprets the two bytes as a short
and fgets the value 0x0102. When it looks at un.c, it interprets those
same two bytes as an array of char, and fgets two different values, one
for each char, giving {0x02, 0x01}.

In general, if you need to care about this, you're doing something
that's non-portable and comp.lang.c is usually not the right place to
ask. But the basics of how representations and values interact are
well within the scope of comp.lang.c (and because of that I think the
claim elsethread that your question should have been posted elsewhere
is unjustified).


dave
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top