Real Life Unions

K

Kenny McCormack

Richard said:
Kenny McCormack said:
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);
}
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.
 
B

bluejack

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

Yevgen Muntyan

bluejack said:
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
 
K

Keith Thompson

bluejack said:
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.
 
D

Default User

Keith said:
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
 
O

Old Wolf

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).
 
O

Old Wolf

Kenny McCormack said:
Richard Heathfield said:
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);
}
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.
 
R

Richard Heathfield

Yevgen Muntyan said:
Keith said:
Adrian Hawryluk said:
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.
 
R

Richard Heathfield

Old Wolf said:
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.
 
K

Kenny McCormack

Richard Heathfield said:
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.
 
Y

Yevgen Muntyan

Richard said:
Yevgen Muntyan said:
Keith said:
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.

You do understand the very point of Kenny's statement: you
can do without unions anything you can do with them. He used word
"struct", indeed, so you got a chance to correct him. But then
how about my "counterexample"? If we're as pedantic as you love
to be (when you find it convenient), then your counterexample
was wrong.
If you really really are saying that you wanted to correct
the factual error in Kenny's statement, then you're either
lying or you do as you usually do - posts where every letter
is correct but post as whole doesn't carry any useful
information. If you wanted to fight a troll a little, then
just say so. I doubt anyone cares about you being always
always correct, I'd think people respect you for other things,
certainly not for your terrible nitpicking attitude.

Best regards,
Yevgen
 
C

CBFalconer

Richard said:
Kenny McCormack said:
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);
}
putchar('\n');


But, strictly speaking, that's illegal, because you are reading
from a variant other than that last stored. The proper way to
perform that is:

double d;
char *dcp;
size_t i;

dcp = &d;
for (i = 0; i < sizeof(double); i++) printf("%02X", *(dcp + i));
putchar('\n');
 
C

CBFalconer

Richard said:
Old Wolf said:
.... snip ...

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.

Hmm, you've done it to me. What conclusions should I draw?
 
R

Richard Heathfield

CBFalconer said:
Hmm, you've done it to me. What conclusions should I draw?

Several benign possibilities (into which it would be tedious to go) do
exist, so there is no need to panic at this stage. :)
 
R

Richard Heathfield

CBFalconer said:
Richard said:
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);
}
putchar('\n');


But, strictly speaking, that's illegal, because you are reading
from a variant other than that last stored.


No, it isn't illegal. See 3.3.2.3. "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." Since
when did we translate "implementation-defined" as "illegal"? After all,
printf("%d\n", INT_MAX); is implementation-defined...
 
C

Chris Dollin

Richard said:
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);
}
putchar('\n');


I think you should present this with the "furniture",
/as an example of best practice/ on CLC.
 
R

Richard Heathfield

Chris Dollin said:
Richard said:
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);
}
putchar('\n');


I think you should present this with the "furniture",
/as an example of best practice/ on CLC.


And since you asked so nicely, Chris, I'm very glad to oblige:

#include <stdio.h>

union U { double d; unsigned char ir[sizeof(double)]; };

int main(void)
{
union U u;
size_t i;
u.d = 3.14159;
puts("The obj rep of (double)3.14159 on this system is:");

for(i = 0; i < sizeof(double); i++)
{
printf("%02X", u.ir);
}
putchar('\n');

return 0;
}


On my system, the above program produced the following output:

The obj rep of (double)3.14159 on this system is:
6E861BF0F9210940
 
C

CBFalconer

Richard said:
CBFalconer said:
Richard said:
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);
}
putchar('\n');


But, strictly speaking, that's illegal, because you are reading
from a variant other than that last stored.


No, it isn't illegal. See 3.3.2.3. "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." Since when did we translate
"implementation-defined" as "illegal"?
After all, printf("%d\n", INT_MAX); is implementation-defined...


It is to me. I don't want the action of my software to be
dependant on the whims or profit motives of a William Gates.

BTW, you might consider making your standard references correspond
to some version younger than 18. For the benefit of others, try
6.5.2.3, constraint #5.
 
K

Kenneth Brody

Yevgen Muntyan wrote:
[...]
You do understand the very point of Kenny's statement: you
can do without unions anything you can do with them. He used word
"struct", indeed, so you got a chance to correct him. But then
how about my "counterexample"? If we're as pedantic as you love
to be (when you find it convenient), then your counterexample
was wrong.
[...]

What about importing some data file that you get from a customer
and/or vendor? The file layout is such that every "record" is the
same length, the first X chars are an indicator of how the rest of
the "record" are to be handled, and the actual layout of the rest
of the "record" varies based on the type indicator.

Yes, to be truly 100% portable without the need to give any special
compiler flags, or worry about padding or byte orders or anything
else, I guess you really need to fread() the "record" into a buffer,
and then manually memmove() things to where you want.

However, assuming that you can coerce the compiler into laying out
a struct that exactly matches the "record" layout (which is not an
unreasonable assumption even in "the real world"), the use of a
single struct, rather than a union of different structs for each
layout, is needless overhead.

Yes, you _can_ do it that way. It just makes more sense to use
the union. (Why move things around to other structs, when the
data is already there in the union?)

You could also do away with for loops, "?:" expressions, all data
types other than "int" and "float" (simply make them the largest
integer and floating types available), and lots of other things
in the language.

--
+-------------------------+--------------------+-----------------------+
| 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]>
 
Y

Yevgen Muntyan

Kenneth said:
Yevgen Muntyan wrote:
[...]
You do understand the very point of Kenny's statement: you
can do without unions anything you can do with them. He used word
"struct", indeed, so you got a chance to correct him. But then
how about my "counterexample"? If we're as pedantic as you love
to be (when you find it convenient), then your counterexample
was wrong.
[...]

What about importing some data file that you get from a customer
and/or vendor? The file layout is such that every "record" is the
same length, the first X chars are an indicator of how the rest of
the "record" are to be handled, and the actual layout of the rest
of the "record" varies based on the type indicator.

Yes, to be truly 100% portable without the need to give any special
compiler flags, or worry about padding or byte orders or anything
else, I guess you really need to fread() the "record" into a buffer,
and then manually memmove() things to where you want.

However, assuming that you can coerce the compiler into laying out
a struct that exactly matches the "record" layout (which is not an
unreasonable assumption even in "the real world"), the use of a
single struct, rather than a union of different structs for each
layout, is needless overhead.
Yes.

Yes, you _can_ do it that way.
Yes.

It just makes more sense to use
the union. (Why move things around to other structs, when the
data is already there in the union?)
Yes.

You could also do away with for loops, "?:" expressions, all data
types other than "int" and "float" (simply make them the largest
integer and floating types available), and lots of other things
in the language.

Yes.

That's the funny thing, "you can do without unions anything you can do
with them", which is true. It's also true that it'd be stupid not
to use what is more appropriate. Look at this:
> 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).

While it's clear that "with a struct" was a plain mistake (not even a
mistake in strictest sense, when we get as pedantic as possible), "not
allowed" part is not completely true, "regulars" are allowed to talk
about anything they want here; he was correct in the very idea that
you can avoid using unions, and any justification for using union
is either off-topic (like memory saving) or a matter of style (like
X events example). It's also true that what your example is
completely off-topic here, even more off-topic than usual, since you
are saving/loading structure content and that's non-portable, breaks
across implementations, may break even on the same implementation, etc.

Kenny made a good point about it, perhaps not in the best form, but
that's Kenny, "admitted troll it's best to ignore him" as some say. The
OP was very lucky that "regulars" were in good mood, or maybe common
sense worked in this case for some reason. Or perhaps they interpreted
it as "what are strictly-conforming examples of using union", which
is unlikely to be what OP asked about.

Yevgen
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top