By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,137 Members | 1,024 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,137 IT Pros & Developers. It's quick & easy.

Real Life Unions

P: n/a

A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

Granted: it makes it possible to save a few bytes of storage when you
have something that can be a chicken or a rooster, but not both, and
you're always going to know which it is.

But I don't think I've ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that's asking for trouble.

That said, I don't write device drivers, kernels, or software for
embedded devices. Space is not usually the constraint that concerns
me: clarity, maintainability, and buglessness are almost always my #1
goals.

But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer's toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!

Mar 9 '07 #1
Share this Question
Share on Google+
67 Replies


P: n/a
bluejack wrote:
A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

Granted: it makes it possible to save a few bytes of storage when you
have something that can be a chicken or a rooster, but not both, and
you're always going to know which it is.

But I don't think I've ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that's asking for trouble.

That said, I don't write device drivers, kernels, or software for
embedded devices. Space is not usually the constraint that concerns
me: clarity, maintainability, and buglessness are almost always my #1
goals.

But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer's toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!
IMHO unions are closer to the dark corners than to the
well-lit top drawer, but they're a tool that would be missed
if someone borrowed them and forgot to return them to your
tool chest.

"Space-saving" has become something of a dirty word, along
with "efficiency." But this is largely a backlash against
excess, against the ritualistic drive to save one more byte
or one more microsecond in a "Hello, world!" program. There
remain situations where savings are important.

And among those, space-saving situations arise more often
than (justifiable) time-saving situations. You've mentioned
the use of unions in "poor man's O-O" polymorphic situations,
and it's easy to see that in a rich object hierarchy with a
lot of more-than-kin-but-less-than-kind relationships the space
savings could be huge. Also, in such situations space savings
can easily equate to time savings: compared to the modern CPU,
memory is d-o-g s-l-o-w and getting slower (we reward our memory
manufacturers for density and for cost, not for speed). If you
can pack four Thing instances into a cache line instead of just
two, you stand a chance of cutting the cache miss rate in half
and making your program 30-60% faster. That sort of efficiency
isn't in the "dirty word" department; it's nothing like the
foolish exercise of shaving a microsecond off a loop that will
run three times total.

You mentioned device drivers. There's a field that's ripe
for polymorphic programming: You'll have a generic framework
that bridges between the device-blind and device-aware parts
of the system, and maybe in the device-aware layer you'll have
further abstraction (we're in the SCSI driver, but are we
talking to a disk or to a tape?). A convenient way to build
such frameworks is to let the lowest-level pieces build structs
with all the information their specific devices need, and then
hand them off to higher-level layers that are unaware of the
specifics. This is polymorphism in action, chum, and unions
are a fine way to achieve it. Not the only way, but a good one.

So, always look for the union label.

--
Eric Sosman
es*****@acm-dot-org.invalid
Mar 9 '07 #2

P: n/a
bluejack <bl******@gmail.comwrote:
>Feel free to provide instructive examples of great moments in Union
history!
Some Internet sockets implementations used to use a union like this
(some probably still do) for IPv4 addresses:

struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
}
#define s_addr S_un.S_addr

This way you could look at the internet address as 4 8-bit chunks, 2
16-bit chunks, or 1 32-bit chunk (using the define to access it as
"foo.s_addr".)

Turns out most people used the 32-bit representation, and under Linux,
anyway, the union is long gone:

typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};

But looking down the code a little more, union is used again for the
IPv6 stuff:

/* IPv6 address */
struct in6_addr
{
union
{
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};

-Beej

Mar 9 '07 #3

P: n/a
bluejack wrote:
A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.
<snip>
>
But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer's toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!
One large swag of code that uses (big) unions is the standard Unix
windowing environment, Xlib. All X events are represented as structures
within one union, where the first structure member is the event ID.

--
Ian Collins.
Mar 9 '07 #4

P: n/a
bluejack wrote:
[...]
But I don't think I've ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that's asking for trouble.

That said, I don't write device drivers, kernels, or software for
embedded devices. Space is not usually the constraint that concerns
me: clarity, maintainability, and buglessness are almost always my #1
goals.

But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer's toolkit, or whether they were
more like an old awl kicking around the dark corners of the box. Feel
free to provide instructive examples of great moments in Union history!
One of the commercial programs I worked on supports a plug-in API that
uses unions. Plug-ins are passed a pointer to a function,

int ( *execute )( void *, LWCommandCode cmd, int argc,
const DynaValue *argv, DynaValue *result );

that can be used to invoke any of several hundred commands implemented
by the program. The command's arguments and return value are wrapped
in DynaValues, a union of more primitive types,

http://home.comcast.net/~erniew/lwsdk/docs/dynaval.html

so that commands can take arguments and return values of arbitrary
type.

That's obviously not the only way this could be handled. The program
could supply a structure or an array containing pointers to every
command function, for example. But using the one execute() function
greatly simplifies the linkage between program and plug-in, makes it
possible for the program to type-check the command arguments, and makes
forward and backward compatibility much easier to support.

Different versions of the program support different sets of commands.
Newer versions have new commands not supported by older versions, and
commands are occasionally deprecated. Using the execute() mechanism,
a single plug-in binary will work with all versions of the program. If
the plug-in attempts to execute() a command that isn't supported, the
program can handle that gracefully, and therefore so can the plug-in.
With a structure or table of function pointers, the program and plug-in
would potentially be meeting at a mismatched interface, and bad things
would happen that neither could control.

This isn't arcane: communication between separate execution units is
pretty commonplace. Nor are unions being used merely to save a few
bytes. And it's not polymorphism in the typical sense: we wouldn't say
that we're defining hundreds of variants of execute().

The plug-in API does provide an alternative,

int ( *evaluate )( void *, const char *cmdstring );

in which the command and its arguments are passed in a string. There
are arguments favoring both approaches.

- Ernie http://home.comcast.net/~erniew
Mar 9 '07 #5

P: n/a
On Thu, 08 Mar 2007 17:23:45 -0800, bluejack wrote:
A recent post asking for help with unions reminded me of this
component of the C language that I have only used a couple of times,
and those almost entirely out of personal whim -- Unions for the sake
of Unions simply because I wanted to see one in action.

Granted: it makes it possible to save a few bytes of storage when you
have something that can be a chicken or a rooster, but not both, and
you're always going to know which it is.

But I don't think I've ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that's asking for trouble.
I do use unions for space savings, and I often run across situations where
that benefit is significant. But more than that, when I use unions I use
them because they make my code more concise, and the intent expressed.

Most recent example, reading an interleaved RTSP stream. Interleaved
means that RTP packets (normally sent over UDP) are mixed in w/ the RTSP
stream control exchange (on TCP). When you break those down there are
several different types of RTP messages, and several different types of
RTSP messages. But, at the front of the stream processing pipeline, you
just want to grab the next message off of the stream, and at the other end
spit out another generic message. So, you can imagine unions come in very
handy here, and they make the code quite digestible.

When you have a complex structure, it can be hard to keep track of each
member, and what its used for. A union says, "these elements are
mutually exclusive, yet share a similar relationship to this parent".
Being able to convey such relationships in code is priceless.

I suppose its sort of obvious in the above that I usually employ unions
as members within larger structures, and not as standalone data
structures.
Mar 9 '07 #6

P: n/a
bluejack wrote:
[...]
But I don't think I've ever encountered a problem where I smacked
myself in the head and said, "A union would be perfect for this!" It
always seems like a design error to go jamming different types into a
single symbol, or at least a design that's asking for trouble.
[...]

Consider a database in which there could be multiple types of records
in the file, with the layout being describe with:

struct record
{
int type;
union
{
TYPE_A A;
TYPE_B B;
TYPE_C C;
}
data;
};

Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Mar 9 '07 #7

P: n/a
In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
....
>Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)
You are all, of course, talking around the problem as usual.

The point is that there is nothing topical in this newsgroup that you
can do with a union that you couldn't do with a struct (at the cost of
using more memory/space - another thing we're not allowed to talk about
here).

Mar 9 '07 #8

P: n/a
Kenny McCormack wrote:
In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
...
>Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)

You are all, of course, talking around the problem as usual.

The point is that there is nothing topical in this newsgroup that you
can do with a union that you couldn't do with a struct (at the cost of
using more memory/space - another thing we're not allowed to talk about
here).
If you are implying that you can always cast a struct over any address,
then ok, but doing so is not... as safe? as intuitive? and it looses the
meaning except in documentation (which every programmer does, right? ;))

A union can be used to group structs which can be used in place of each
other. They can also be used to find out the largest amount of memory
to have to allocate at compile time given a set of structs. This
happens in the case of message passing using something like QNiX
Send-Receive-Reply mechanism, where it requires that you copy the
message from one process space to another, you need to allocate an
appropriate buffer size.

The polymorphic *like* ability is very useful and is safer than a
programmer casting as the cast could be anything, where as a union at
least instructs the programmer that the type should be one of a smaller
defined set.
Adrian
Mar 9 '07 #9

P: n/a
In article <HTgIh.27500$lY6.10230@edtnps90>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
>Kenny McCormack wrote:
>In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
...
>>Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)

You are all, of course, talking around the problem as usual.

The point is that there is nothing topical in this newsgroup that you
can do with a union that you couldn't do with a struct (at the cost of
using more memory/space - another thing we're not allowed to talk about
here).
If you are implying that you can always cast a struct over any address,
then ok, but doing so is not... as safe? as intuitive? and it looses the
meaning except in documentation (which every programmer does, right? ;))
I'm not sure what you mean by this, but all I'm saying is that if you
have:

union foo { object1;object2;object3 }

that is exactly the same as:

struct foo { object1;object2;object3 }

in terms of what you can with it.

In particular, using unions to do on-the-fly type "spoofing" (which I
always thought was their primary purpose) is OT in this NG.

Mar 9 '07 #10

P: n/a
On Mar 9, 7:29 am, Kenneth Brody <kenbr...@spamcop.netwrote:
struct record
{
int type;
union
{
TYPE_A A;
TYPE_B B;
TYPE_C C;
}
data;
};
Right; this is how I've used them in the past, and the need to provide
an explicit type indicator to inform the handling code what is in the
union is displeasing to me;

However, with many of the examples provided, I see how unions can
create flexible, and extensible *interfaces*. The case of the X11
event model being a prime example. This, to me, was the enlightenment
I sought, and I thank everyone for their input!

Back to my original silly metaphor, if something is a Chicken or a
Rooster but not both you might define a union to express this. Then,
defining a function that accepts the type indicator and the union, if
at a later date your code grows to encompass Cornish Game Hens,
Turkeys, and Roast Peking Duck, you do not need to change the
interface.

Naturally, the same thing could be effectively accomplished with a
type indicator and a void pointer, but all things considered, a union
is safer than a void pointer any day.

And, sure, a struct *could* do the job: but if the types are mutually
exclusive, and you will need a type indicator to point code to the
meaningful member, then a union is the *right* structure.

Thanks!

Mar 9 '07 #11

P: n/a
On Fri, 09 Mar 2007 17:05:10 +0000, Kenny McCormack wrote:
In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
...
>>Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)

You are all, of course, talking around the problem as usual.

The point is that there is nothing topical in this newsgroup that you
can do with a union that you couldn't do with a struct (at the cost of
using more memory/space - another thing we're not allowed to talk about
here).
By that same logic there's nothing one could do w/ a struct that one
couldn't do with careful, mindful, and tedious bit operations on elements
of arrays of unsigned char.

There's nothing one can do with typedef's that one cannot do without. We
can even begin throwing out arithmetic operators.
Mar 9 '07 #12

P: n/a
William Ahern <wi*****@25thandClement.comwrites:
There's nothing one can do with typedef's that one cannot do
without.
How do you call va_arg for a function pointer type without
typedef?
--
"C has its problems, but a language designed from scratch would have some too,
and we know C's problems."
--Bjarne Stroustrup
Mar 9 '07 #13

P: n/a
On Mar 9, 1:23 am, "bluejack" <bluuj...@gmail.comwrote:
A recent post asking for help with unions reminded me of this
...
free to provide instructive examples of great moments in Union history!
Let me add another question to this. One of my applications uses a
sparse matrix library. Values are encoded as floats or doubles (it is
a typedef, set at compile time).
Now there are occasions where I'd like to store something else, say a
pointer to some object specific to that matrix entry.
The need arises only infrequently. I then code in whatever way seems
logical (using ad hoc data structures), but I've wondered about
replacing the value with a union of say { void* obj, double val }. It
probably hinges on the extent to which code can be reused for the two
separate cases. I believe there is certainly scope for that in my
application - it will be application specific in general.

It is tempting to compare this with some container type that works on
(void*) data with callbacks operating on the data (say a generic hash
library). In case of a sparse matrix this approach would penalize the
default case (doubles) prohibitively in terms of speed. I believe the
union approach would probably be alright in this respect (but you
don't get the same code genericity).

Any thoughts on this?
stijn

Mar 9 '07 #14

P: n/a
On Fri, 09 Mar 2007 13:26:45 -0800, Ben Pfaff wrote:
William Ahern <wi*****@25thandClement.comwrites:
>There's nothing one can do with typedef's that one cannot do
without.

How do you call va_arg for a function pointer type without
typedef?
Aha! You don't. You could manage just as well without function pointers.

Ok. Now this is just getting silly. =)
Mar 9 '07 #15

P: n/a
bluejack wrote:
>
On Mar 9, 7:29 am, Kenneth Brody <kenbr...@spamcop.netwrote:
struct record
{
int type;
union
{
TYPE_A A;
TYPE_B B;
TYPE_C C;
}
data;
};

Right; this is how I've used them in the past, and the need to provide
an explicit type indicator to inform the handling code what is in the
union is displeasing to me;
[...]
Back to my original silly metaphor, if something is a Chicken or a
Rooster but not both you might define a union to express this. Then,
defining a function that accepts the type indicator and the union, if
at a later date your code grows to encompass Cornish Game Hens,
Turkeys, and Roast Peking Duck, you do not need to change the
interface.

Naturally, the same thing could be effectively accomplished with a
type indicator and a void pointer, but all things considered, a union
is safer than a void pointer any day.
[...]

What about a linked list of fowl? Yes, the linked list could be
a list of void pointers to the item, but unions allow you to have
a list of the items themselves. (Ditto for "array" instead of
"linked list", though in that case you need to make sure that if
the size of the union changes, you need to rebuild any libraries
using it.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Mar 9 '07 #16

P: n/a
Ben Pfaff wrote:
William Ahern <wi*****@25thandClement.comwrites:
>There's nothing one can do with typedef's that one cannot do
without.

How do you call va_arg for a function pointer type without
typedef?
#include <stdio.h>
#include <stdarg.h>

void foo (void)
{
printf ("Hi there!\n");
}

void func (int a, ...)
{
va_list ap;
va_start (ap, a);

{
void (*f) (void) = va_arg (ap, void(*)(void));
if (f)
f ();
}

va_end (ap);
}

int main (void)
{
void (*f) (void) = foo;
func (0, f);
func (0, foo);
return 0;
}
Mar 9 '07 #17

P: n/a
Yevgen Muntyan <mu****************@tamu.eduwrites:
Ben Pfaff wrote:
>William Ahern <wi*****@25thandClement.comwrites:
>>There's nothing one can do with typedef's that one cannot do
without.

How do you call va_arg for a function pointer type without
typedef?
void (*f) (void) = va_arg (ap, void(*)(void));
That is non-standard code:

7.15.1.1 The va_arg macro

Synopsis
1 #include <stdarg.h>
type va_arg(va_list ap, type);

[...] The parameter type shall be a type name specified such
that the type of a pointer to an object that has the
specified type can be obtained simply by postfixing a * to
type.

--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Mar 9 '07 #18

P: n/a
On 8 Mar 2007 17:23:45 -0800, in comp.lang.c , "bluejack"
<bl******@gmail.comwrote:
>But I was curious, in the community of c programmers, whether Unions
had an honored place in the engineer's toolkit,
They're ideal for interfaces. Take a look at a sockets implementation
sometime. A popular programming language also uses a union "under the
hood" to store its untyped data type.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 9 '07 #19

P: n/a
Ben Pfaff wrote:
Yevgen Muntyan <mu****************@tamu.eduwrites:
>Ben Pfaff wrote:
>>William Ahern <wi*****@25thandClement.comwrites:

There's nothing one can do with typedef's that one cannot do
without.
How do you call va_arg for a function pointer type without
typedef?
> void (*f) (void) = va_arg (ap, void(*)(void));

That is non-standard code:

7.15.1.1 The va_arg macro

Synopsis
1 #include <stdarg.h>
type va_arg(va_list ap, type);

[...] The parameter type shall be a type name specified such
that the type of a pointer to an object that has the
specified type can be obtained simply by postfixing a * to
type.
Oh, so that's UB. I believed gcc would emit a warning in a case like
this (with -ansi -pedantic -Weverything).

Thanks,
Yevgen
Mar 9 '07 #20

P: n/a
William Ahern wrote:
On Fri, 09 Mar 2007 17:05:10 +0000, Kenny McCormack wrote:
>In article <45***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.netwrote:
...
>>Another example is passing "messages" to an event-driven program.
There are multiple types of messages, such as keyboard input, mouse
input, windows messages, and so on. By creating a struct which
contains the message type, plus a union of all of the different
types of messages, you can pass the struct to a single event
handler routine, rather than having to pass the message to a
different function for each type of event. (Plus, you can add
new event types without affecting existing event handlers.)
You are all, of course, talking around the problem as usual.

The point is that there is nothing topical in this newsgroup that you
can do with a union that you couldn't do with a struct (at the cost of
using more memory/space - another thing we're not allowed to talk about
here).

By that same logic there's nothing one could do w/ a struct that one
couldn't do with careful, mindful, and tedious bit operations on elements
of arrays of unsigned char.

There's nothing one can do with typedef's that one cannot do without. We
can even begin throwing out arithmetic operators.
Get rid of functions, macros, types... Hey! We're back to Machine
Language! ;)

BTW, who states what is and is not talked about here?
Adrian
Mar 10 '07 #21

P: n/a
Adrian Hawryluk said:

<snip>
BTW, who states what is and is not talked about here?
The topic of comp.lang.c is the computer programming language called C.
Legally, anyone here can talk about anything that doesn't breach their
ISP's T&Cs. Socially speaking, however, discussing anything /other/
than C will cost you a certain amount of 'capital', and that 'capital'
can take a long time to acquire (by patiently and correctly answering C
questions for a rather long time). Such things are not tracked formally
- everyone has their own feel for who is an on-topic kinda person and
who is not. Newbies, not surprisingly, often get this wrong.

Those who are not on-topic kinda people will[*] tend to fade away from
comp.lang.c, and find other newsgroups (e.g. comp.unix.programmer or
comp.os.ms-windows.programmer.win32 or the like) - and that's fine. And
of course there's nothing to stop people subscribing to more than one
group.
[*] Except for some of the trolls.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 10 '07 #22

P: n/a
"bluejack" <bl******@gmail.comwrote:

# Back to my original silly metaphor, if something is a Chicken or a
# Rooster but not both you might define a union to express this. Then,
# defining a function that accepts the type indicator and the union, if
# at a later date your code grows to encompass Cornish Game Hens,
# Turkeys, and Roast Peking Duck, you do not need to change the
# interface.

Unions require you distribute code to deal with each
possible union element throughout the code. Sometimes
this okay to best, especially when the union is small
and does not evolve. In other cases, everytime you
extend a union you have to track down all cases
throughout the code.

Object-oriented techniques instead collect all the
code for each union element in one place and let
you extend the union without perturbing other union
elements (theoretically).

You can do object-oriented programming in C.

# struct record
# {
# int type;
# union
# {
# TYPE_A A;
# TYPE_B B;
# TYPE_C C;
# }
# data;
# };

// Define the Object.

struct record {
T (*method1)(struct record *self,...);
T (*method2)(struct record *self,...);
T (*method3)(struct record *self,...);
...
}
#define method1(self,...) ((self)->method1)((void*)(self),...)
....

// Implement TYPE_A variant of object.

struct recordA {
T (*method1)(struct record *self,...);
T (*method2)(struct record *self,...);
T (*method3)(struct record *self,...);
...
TYPE_A A;
}
T Amethod1(struct record *self0,...) {
struct recordA *self = (struct recordA*)self0;
...
}
struct record *newA(...) {
struct recordA *a = malloc(sizeof(struct recordA);
a->method1 = Amethod1;
...
return (struct record*)a;
}

etc

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Title does not dictate behaviour.
Mar 10 '07 #23

P: n/a
On Sat, 10 Mar 2007 10:37:16 +0000, SM Ryan wrote:
<snip>
# struct record
# {
# int type;
# union
# {
# TYPE_A A;
# TYPE_B B;
# TYPE_C C;
# }
# data;
# };
If you have a type "attribute", then very often its a good idea to use an
enum, because almost as often you will (or should) have a switch
statement (or statements) to control code flow for some set of the types.

Compilers like GCC can be told to warn when a switch occurs on
an enumerated type, and all the enumerated values are not accounted for.
If you're an advocate of defensive programming--at least in some
circumstances--then it can prove quite useful.

(I qualify with the defensive programming bit because the GCC checks can be
quite naive, and don't seem to do any sort of inter-procedural flow
analysis; in which case, the warning(s) could potentially be more a
nuisance than useful feedback on program correctness, and so defensible
only on pragmatic grounds).
Mar 12 '07 #24

P: n/a
Richard Heathfield wrote:
Adrian Hawryluk said:

<snip>
>BTW, who states what is and is not talked about here?

The topic of comp.lang.c is the computer programming language called C.
Legally, anyone here can talk about anything that doesn't breach their
ISP's T&Cs. Socially speaking, however, discussing anything /other/
than C will cost you a certain amount of 'capital', and that 'capital'
can take a long time to acquire (by patiently and correctly answering C
questions for a rather long time). Such things are not tracked formally
- everyone has their own feel for who is an on-topic kinda person and
who is not. Newbies, not surprisingly, often get this wrong.

Those who are not on-topic kinda people will[*] tend to fade away from
comp.lang.c, and find other newsgroups (e.g. comp.unix.programmer or
comp.os.ms-windows.programmer.win32 or the like) - and that's fine. And
of course there's nothing to stop people subscribing to more than one
group.
[*] Except for some of the trolls.
Thanks for the info.

However, I and it looks like a few others don't see it your way that
unions are not topical.
Adrian

--
================================================== ========
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
================================================== ========
Mar 13 '07 #25

P: n/a
Adrian Hawryluk said:

<snip>
Thanks for the info.

However, I and it looks like a few others don't see it your way that
unions are not topical.
Huh?!?!? Of course unions are topical! See, for example, 6.7.2.1.
There's even a 'union' keyword. Unions not topical? Never heard such
tosh.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 13 '07 #26

P: n/a
In article <alxJh.93939$cE3.58567@edtnps89>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
....
>However, I and it looks like a few others don't see it your way that
unions are not topical.
Whoever said that?

What *I* said, which you may have misunderstood, was that there's no
*use* of unions that is topical here that can't just as easily be done
with a struct. What this means is that unions *could* be removed from the
standard with no loss of functionality *as far as this ng is concerned*
(not true, of couse, as far as the *real world* is concerned).

That's not to say, of course, that there is any chance that they will
(be removed).

Mar 13 '07 #27

P: n/a
Adrian Hawryluk <ad**************************@nospam.comwrote:
However, I and it looks like a few others don't see it your way that
unions are not topical.
_That_ problem is easily solved by not listening to Kenny McTrollmack.

Richard
Mar 13 '07 #28

P: n/a
Kenny McCormack said:
In article <alxJh.93939$cE3.58567@edtnps89>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
...
>>However, I and it looks like a few others don't see it your way that
unions are not topical.

Whoever said that?

What *I* said, which you may have misunderstood, was that there's no
*use* of unions that is topical here that can't just as easily be done
with a struct.
Counter-example:

union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 13 '07 #29

P: n/a
In article <9M*********************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
....
>union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');
When I feed the above trash to my C compiler, I get a bunch of error
messages (said in the spirit of this newsgroup).

Anyway, type-punning was specifically disallowed in this NG a few years
back. You need to keep up.

Mar 13 '07 #30

P: n/a
Kenny McCormack said:
In article <9M*********************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
...
>>union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');

When I feed the above trash to my C compiler, I get a bunch of error
messages
First, learn C. Then add your own furniture to the above code fragment,
to get a fully compilable program. It's not difficult.
(said in the spirit of this newsgroup).

Anyway, type-punning was specifically disallowed in this NG a few
years back. You need to keep up.
Read the Standard more closely, and you will discover your error.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 13 '07 #31

P: n/a
Richard Heathfield wrote:
Adrian Hawryluk said:

<snip>
>Thanks for the info.

However, I and it looks like a few others don't see it your way that
unions are not topical.

Huh?!?!? Of course unions are topical! See, for example, 6.7.2.1.
There's even a 'union' keyword. Unions not topical? Never heard such
tosh.
My apologies, that was miss directed. It was Kenny that said:
>On Fri, 09 Mar 2007 17:05:10 +0000, Kenny McCormack wrote:
>>>
The point is that there is nothing topical in this newsgroup that
you can do with a union that you couldn't do with a struct (at the
cost of using more memory/space - another thing we're not allowed
to >>talk about
>>here).
Sorry again,
Adrian

--
================================================== ========
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
================================================== ========
Mar 13 '07 #32

P: n/a
Kenny McCormack wrote:
In article <alxJh.93939$cE3.58567@edtnps89>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
...
>However, I and it looks like a few others don't see it your way that
unions are not topical.

Whoever said that?

What *I* said, which you may have misunderstood, was that there's no
*use* of unions that is topical here that can't just as easily be done
with a struct. What this means is that unions *could* be removed from the
standard with no loss of functionality *as far as this ng is concerned*
(not true, of couse, as far as the *real world* is concerned).

That's not to say, of course, that there is any chance that they will
(be removed).
Thanks for clarifying.
Adrian

--
================================================== ========
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
================================================== ========
Mar 13 '07 #33

P: n/a
Adrian Hawryluk wrote, On 13/03/07 16:48:

<snip>
Thanks for clarifying.

Adrian

--
================================================== ========
Adrian Hawryluk BSc. Computer Science
----------------------------------------------------------
Specialising in: OOD Methodologies in UML
OOP Methodologies in C, C++ and more
RT Embedded Programming
__--------------------------------------------------__
----- [blog: http://adrians-musings.blogspot.com/] -----
'--------------------------------------------------------'
My newsgroup writings are licensed under the Creative
Commons Attribution-Noncommercial-Share Alike 3.0 License
http://creativecommons.org/licenses/by-nc-sa/3.0/
================================================== ========
Please cut down your signature, half a page is *far* too long. The
convention is up to 4 lines, although a bit longer might not be
commented on, but this is 14. Alternatively I'll just plonk you due to
the annoyance factor.
--
Flash Gordon
Mar 13 '07 #34

P: n/a
In article <3c************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.ukwrote:
....
>Please cut down your signature, half a page is *far* too long. The
convention is up to 4 lines, although a bit longer might not be
commented on, but this is 14. Alternatively I'll just plonk you due to
the annoyance factor.
Which would be best for all concerned. I say, go for it! Keep that sig
intact!

Nobody wants to hear from Fleshy, anyway.

Mar 13 '07 #35

P: n/a
Adrian Hawryluk <ad**************************@nospam.comwrites:
Richard Heathfield wrote:
>Adrian Hawryluk said:
<snip>
>>Thanks for the info.

However, I and it looks like a few others don't see it your way that
unions are not topical.
Huh?!?!? Of course unions are topical! See, for example,
6.7.2.1. There's even a 'union' keyword. Unions not topical? Never
heard such tosh.
My apologies, that was miss directed. It was Kenny that said:
[snip]

Kenny is an admitted troll; he is best ignored.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 13 '07 #36

P: n/a
Keith Thompson wrote:
Adrian Hawryluk <ad**************************@nospam.comwrites:
>Richard Heathfield wrote:
>>Adrian Hawryluk said:
<snip>

Thanks for the info.

However, I and it looks like a few others don't see it your way that
unions are not topical.
Huh?!?!? Of course unions are topical! See, for example,
6.7.2.1. There's even a 'union' keyword. Unions not topical? Never
heard such tosh.
My apologies, that was miss directed. It was Kenny that said:
[snip]

Kenny is an admitted troll; he is best ignored.
Note that in this case he caught even Richard Heathfield (of course
Richard could not resist to be right one more time and use Kenny's
mistake about "using struct"). Funny thing is that Kenny's original
statement was true. I'd think this union thing is good food for
thought about on-topic vs off-topic.

Yevgen
Mar 13 '07 #37

P: n/a
Richard Heathfield wrote:
Kenny McCormack said:
>In article <alxJh.93939$cE3.58567@edtnps89>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
...
>>However, I and it looks like a few others don't see it your way that
unions are not topical.
Whoever said that?

What *I* said, which you may have misunderstood, was that there's no
*use* of unions that is topical here that can't just as easily be done
with a struct.

Counter-example:

union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');
struct S {int foo;}; /* need to use struct somewhere */
double d = 3.14159;
unsigned char ir[sizeof (double)];
memcpy (ir, &d, sizeof d);
....

Now Richard should probably say that it's not as easy, to remain
right.

Yevgen
Mar 13 '07 #38

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
....
>Kenny is an admitted troll; he is best ignored.
Keith is an admitted anal retentive freak; he is best read carefully for
maximal enjoyment.

Mar 13 '07 #39

P: n/a
In article <5RDJh.3145$I56.2881@trnddc06>,
Yevgen Muntyan <mu****************@tamu.eduwrote:
....
>Note that in this case he caught even Richard Heathfield (of course
Richard could not resist to be right one more time and use Kenny's
mistake about "using struct"). Funny thing is that Kenny's original
statement was true. I'd think this union thing is good food for
thought about on-topic vs off-topic.
Heathfield claims, as far as I can tell, that there is a "special
license" in the standard for type punning involving unsigned char.
He may be right about this; I can't be bothered to check because it
doesn't change my underlying point. I.e., even if type punning is
allowable in one obscure special case, it doesn't change the fact that
the standard disallows it in general and that, therefore, the primary
use of unions (*) in the real world is OT here.

(*) That couldn't just as easily be done with a struct.

Mar 13 '07 #40

P: n/a
In article <%VDJh.3147$I56.1682@trnddc06>,
Yevgen Muntyan <mu****************@tamu.eduwrote:
>Richard Heathfield wrote:
>Kenny McCormack said:
>>In article <alxJh.93939$cE3.58567@edtnps89>,
Adrian Hawryluk <ad**************************@nospam.comwrote:
...
However, I and it looks like a few others don't see it your way that
unions are not topical.
Whoever said that?

What *I* said, which you may have misunderstood, was that there's no
*use* of unions that is topical here that can't just as easily be done
with a struct.

Counter-example:

union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');

struct S {int foo;}; /* need to use struct somewhere */
double d = 3.14159;
unsigned char ir[sizeof (double)];
memcpy (ir, &d, sizeof d);
...

Now Richard should probably say that it's not as easy, to remain
right.

Yevgen
Heathfield will remain right in his own mind regardless of any possible
real world events. He's the Usenet equivalent of the "flesh wound"
knight in the Holy Grail.

Mar 13 '07 #41

P: n/a

I think I regret starting this thread. I did get some useful insight
into design choices for unions though.

Mar 13 '07 #42

P: n/a
bluejack wrote:
I think I regret starting this thread. I did get some useful insight
into design choices for unions though.
Don't be upset, you could get way way worse reaction from "regulars"
if you asked a different question about real-life stuff. Kenny's
response is rather amusing (maybe not for innocent person who
doesn't know what comp.lang.c is).

Yevgen
Mar 13 '07 #43

P: n/a
"bluejack" <bl******@gmail.comwrites:
I think I regret starting this thread. I did get some useful insight
into design choices for unions though.
There's no need to apologize. Trolls will troll, and spammers will
spam; they don't need an excuse, and there's not a whole lot you can
do to stop them. You may find that a killfile will improve this
newsgroup's effective signal-to-noise ratio considerably.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 13 '07 #44

P: n/a
Keith Thompson wrote:
"bluejack" <bl******@gmail.comwrites:
I think I regret starting this thread. I did get some useful insight
into design choices for unions though.

There's no need to apologize. Trolls will troll, and spammers will
spam; they don't need an excuse, and there's not a whole lot you can
do to stop them. You may find that a killfile will improve this
newsgroup's effective signal-to-noise ratio considerably.
He's just Google Groups, which doesn't have a built-in filtering
capability. I believe there are some guys who have come with plug-ins
for particular browsers.

Another solution is to get news service and a real^H^H^H^H dedicated
newsreader.


Brian
Mar 13 '07 #45

P: n/a
On Mar 14, 9:58 am, gaze...@xmission.xmission.com (Kenny McCormack)
wrote:
I.e., even if type punning is
allowable in one obscure special case, it doesn't change the fact that
the standard disallows it in general and that, therefore, the primary
use of unions (*) in the real world is OT here.

(*) That couldn't just as easily be done with a struct.
Things disallowed by the standard are not off-topic (per se).

Mar 13 '07 #46

P: n/a
On Mar 14, 5:29 am, Richard Heathfield <r...@see.sig.invalidwrote:
Kenny McCormack said:
Richard Heathfield <r...@see.sig.invalidwrote:
...
>union U { double d; unsigned char ir[sizeof(double)]; };
union U u;
size_t i;
u.d = 3.14159;
for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir[i]);
}
putchar('\n');
When I feed the above trash to my C compiler, I get a bunch of error
messages

First, learn C. Then add your own furniture to the above code fragment,
to get a fully compilable program. It's not difficult.
You regularly make posts in response to others who omit the furniture,
pointing out that they are causing UB by calling printf without a
prototype in scope, etc. Sometimes there is not even any other point
in your post. So I think it's a bit rich for you to come back with
criticism when somebody else does it back to you.

Mar 13 '07 #47

P: n/a
Yevgen Muntyan said:
Keith Thompson wrote:
>Adrian Hawryluk <ad**************************@nospam.comwrites:
>>Richard Heathfield wrote:
Adrian Hawryluk said:
<snip>

Thanks for the info.
>
However, I and it looks like a few others don't see it your way
that unions are not topical.
Huh?!?!? Of course unions are topical! See, for example,
6.7.2.1. There's even a 'union' keyword. Unions not topical? Never
heard such tosh.

My apologies, that was miss directed. It was Kenny that said:
[snip]

Kenny is an admitted troll; he is best ignored.

Note that in this case he caught even Richard Heathfield
It isn't a matter of "catching". It seemed to me that Mr McCormack's
article was attempting to make a legitimate, albeit mistaken, point
about C. I ignore most of Mr McCormack's articles, of course, but even
a troll might say something relevant and meaningful on occasion - and I
reserve the right to reply to articles that are relevant and
meaningful.
(of course
Richard could not resist to be right one more time
I don't see being right as something that should be resisted. I could,
however, have resisted posting easily enough. Nevertheless, I felt that
there was something relevant that was worth saying in response to the
article, so I said it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 13 '07 #48

P: n/a
Old Wolf said:
On Mar 14, 5:29 am, Richard Heathfield <r...@see.sig.invalidwrote:
>Kenny McCormack said:

First, learn C. Then add your own furniture to the above code
fragment, to get a fully compilable program. It's not difficult.

You regularly make posts in response to others who omit the furniture,
pointing out that they are causing UB by calling printf without a
prototype in scope, etc.
Yes, that's right, I do - when there is good reason to suspect that they
are unaware of the importance of the furniture. When it is evident to
me that the poster knows the language, I don't do this. I do not see
this as being inconsistent.

If it is your contention that I do not know the language sufficiently
well to be aware of the headers and other furniture that my code would
have needed before being compilable, well, feel free to go on believing
that if it makes you happy.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 13 '07 #49

P: n/a
In article <O-******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
....
>Yes, that's right, I do - when there is good reason to suspect that they
are unaware of the importance of the furniture. When it is evident to
me that the poster knows the language, I don't do this. I do not see
this as being inconsistent.
So speaks the "flesh wound" knight of Usenet.

Mar 13 '07 #50

67 Replies

This discussion thread is closed

Replies have been disabled for this discussion.