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

An example of unions not being type safe?

P: n/a
Okay, so like recently the whole idea of using a Union in C finally
sunk into my skull. Seriously, I think it probably took me 2 years to
catch on what a Union really is. Belated, I mentioned this too my
ultra smart friend who just quit working as a CTO of a wireless
company so he go complete his PhD in particle physics. Anyhow he
mentioned that Unions in C are not typesafe.

Now, how is it possible to violate type safety in Unions?

Chad

Aug 15 '07 #1
Share this Question
Share on Google+
21 Replies


P: n/a

"Chad" <cd*****@gmail.comwrote in message
news:11**********************@q3g2000prf.googlegro ups.com...
Okay, so like recently the whole idea of using a Union in C finally
sunk into my skull. Seriously, I think it probably took me 2 years to
catch on what a Union really is. Belated, I mentioned this too my
ultra smart friend who just quit working as a CTO of a wireless
company so he go complete his PhD in particle physics. Anyhow he
mentioned that Unions in C are not typesafe.

Now, how is it possible to violate type safety in Unions?
#include <stdio.h>

int main(void) {
union {
int i;
double d;
} z;

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
return 0;
}

--
poncho
Aug 15 '07 #2

P: n/a
On Aug 15, 1:17 pm, "Scott Fluhrer" <sfluh...@ix.netcom.comwrote:
"Chad" <cdal...@gmail.comwrote in message
Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
Well, you aren't allowed to do that. Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

? If you follow the rules as to what you are
permitted to do with unions, then I don't see
any violation of type safety.

Aug 15 '07 #3

P: n/a
Old Wolf said:
On Aug 15, 1:17 pm, "Scott Fluhrer" <sfluh...@ix.netcom.comwrote:
>"Chad" <cdal...@gmail.comwrote in message
Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */

Well, you aren't allowed to do that.
False. The behaviour is implementation-defined in C90, and undefined in
C99. Taking advantage of either behaviour is *not* forbidden, although
it does render your program non-portable. I'm not condoning the above
by any means, but it is not true that "you aren't allowed to do that",
any more than it is true that you are not allowed to define an array
with 1 << CHAR_BIT elements (implementation-defined behaviour) or
dereference a pointer to video memory under MS-DOS (undefined
behaviour).
Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */
Yes. What makes it possible to break the type system is the existence of
multiple types and the ability to convert between them.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 16 '07 #4

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Old Wolf said:
[...]
>Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

Yes. What makes it possible to break the type system is the existence of
multiple types and the ability to convert between them.
Not quite. Being able to convert between types doesn't necessarily
break the type system. For example, a hypothetical 100% typesafe
language might freely allow conversions among different numeric types.
This:
int x = 10;
printf("%f", (double)x);
doesn't break type safety.

What does break type safety in C is the ability to treat an object of
one type as if it were an object of a different type, *without*
coverting the value of the object (i.e., type-punning). Unions and
pointer conversions make this possible.

--
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"
Aug 16 '07 #5

P: n/a
On Aug 16, 12:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Old Wolf said:
"Chad" <cdal...@gmail.comwrote:
z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
Well, you aren't allowed to do that.

False. The behaviour is implementation-defined in C90, and undefined in
C99.
C90 does not have aliasing rules? (Notwithstanding
clauses specific to unions).

Aug 16 '07 #6

P: n/a
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>Old Wolf said:
[...]
>>Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

Yes. What makes it possible to break the type system is the existence
of multiple types and the ability to convert between them.

Not quite. Being able to convert between types doesn't necessarily
break the type system.
I didn't say it did. I said that it was what makes it *possible* to
break the type system. Now, I will accept that it may not be
sufficient, but it is certainly a prerequisite. Without the ability to
convert between types, there is no mechanism for breaking the type
system; and without multiple types, there isn't a type system to break.

The existence of a mechanism for breaking the type system does not imply
that that mechanism must be used. Therefore, the ability to convert
between types doesn't of itself break the type system. Such a mechanism
does, however, remove a significant barrier to such breakage.
For example, a hypothetical 100% typesafe
language might freely allow conversions among different numeric types.
This:
int x = 10;
printf("%f", (double)x);
doesn't break type safety.

What does break type safety in C is the ability to treat an object of
one type as if it were an object of a different type, *without*
coverting the value of the object (i.e., type-punning). Unions and
pointer conversions make this possible.
You're making the same mistake again. That ability does not break type
safety. It merely opens the door to such breakage. Nor are unions and
pointer conversions *necessary* for breaking type safety, since C
thoughtfully provides at least one other type-safety-breaking
mechanism: the ability to write values to, and subsequently read those
values from, a file.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 16 '07 #7

P: n/a
Old Wolf said:
On Aug 16, 12:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Old Wolf said:
>"Chad" <cdal...@gmail.comwrote:
z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
Well, you aren't allowed to do that.

False. The behaviour is implementation-defined in C90, and undefined
in C99.

C90 does not have aliasing rules?
It's hard to prove a negative. Can you show that C90 /does/ have
aliasing rules that disallow the specific code given?

For "disallow", I will on this occasion accept the following meanings:

* the code violates a constraint
* the code contains a syntax error
* the behaviour of the code is undefined [1]

Note that 3.3.2.3 of C89 renders the behaviour implementation-defined,
so any answer has to be able to trump that rendering. C90 will have
different numbering - possibly 6.3.2.3 - but it is well-known that C89
and C90 have basically the same text, except for the insertion of three
"noise" sections.
(Notwithstanding
clauses specific to unions).
The *code* is specific to unions!
[1] In fact, there is no prohibition on taking advantage of undefined
behaviour, but I want to give you every chance to back up your claim
that "you aren't allowed to do that". What I won't do is agree that
implementation-defined behaviour is not allowed.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 16 '07 #8

P: n/a
Richard Heathfield wrote:
Old Wolf said:
Richard Heathfield wrote:
"Chad" <cdal...@gmail.comwrote:
z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
False. The behaviour is implementation-defined in C90,
C90 does not have aliasing rules?

It's hard to prove a negative. Can you show that C90 /does/ have
aliasing rules that disallow the specific code given?
I don't have a copy of C90, hence why I'm asking you.
Note that 3.3.2.3 of C89 renders the behaviour implementation-defined,
so any answer has to be able to trump that rendering.
Yes. For example, in C99 the behaviour is undefined
because it is explicitly undefined to alias a float
as an int (regardless of whether a union is involved).
It seems a reasonable assumption that C90 has similar
aliasing rules, although I'm unable to look it up.
Aug 16 '07 #9

P: n/a
On Aug 15, 8:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Old Wolf said:
On Aug 15, 1:17 pm, "Scott Fluhrer" <sfluh...@ix.netcom.comwrote:
"Chad" <cdal...@gmail.comwrote in message
Now, how is it possible to violate type safety in Unions?
z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
Well, you aren't allowed to do that.

False. The behaviour is implementation-defined in C90, and undefined in
C99.
It is actually undefined in C90 (the fact that the Standard states it
is implementation-defined is a defect). In C99 it is only undefined
behavior if the result is a trap representation.

Robert Gamble

Aug 16 '07 #10

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>Old Wolf said:
[...]
>>>Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

Yes. What makes it possible to break the type system is the existence
of multiple types and the ability to convert between them.

Not quite. Being able to convert between types doesn't necessarily
break the type system.

I didn't say it did. I said that it was what makes it *possible* to
break the type system. Now, I will accept that it may not be
sufficient, but it is certainly a prerequisite. Without the ability to
convert between types, there is no mechanism for breaking the type
system; and without multiple types, there isn't a type system to break.

The existence of a mechanism for breaking the type system does not imply
that that mechanism must be used. Therefore, the ability to convert
between types doesn't of itself break the type system. Such a mechanism
does, however, remove a significant barrier to such breakage.
[...]

I think we're saying the same thing in different words.

I'm thinking of "breaks the type system" and "makes it possible to
break the type system" as being essentially synonymous. Being able to
convert between types is not sufficient to make it possible to break
the type system (if, for example, only conversions among numeric types
are allowed).

I think the difference is that I'm talking about language features
breaking the type system, and you're talking about programs actually
*using* those features to break the type system. A language that
allows arbitary assignments between distinct types has a broken type
system, even if it's possible to write programs in that language that
don't take advantage of that brokenness.

Note that "broken" isn't necessarily a bad thing. Sometimes you want
to bypass type checking.

--
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"
Aug 16 '07 #11

P: n/a
Keith Thompson said:

<snip>
I think we're saying the same thing in different words.
No, we *are*!

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 16 '07 #12

P: n/a
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
<snip>
>Not even the ISO C Committee can change the past.

Strictly speaking, the committee corrected the C90 standard by issuing
the C99 standard. They're not going to issue corrections to a
standard that's officially obsolete. (I know that C90 is still a de
facto current standard, but the committee isn't going to act on that
basis.)
All absolutely true, of course. Nevertheless, C90 remains topical here,
and in C90 (sans TCs) the behaviour in question is, and will always
remain, implementation-defined.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 16 '07 #13

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>Richard Heathfield <rj*@see.sig.invalidwrites:

<snip>
>>Not even the ISO C Committee can change the past.

Strictly speaking, the committee corrected the C90 standard by issuing
the C99 standard. They're not going to issue corrections to a
standard that's officially obsolete. (I know that C90 is still a de
facto current standard, but the committee isn't going to act on that
basis.)

All absolutely true, of course. Nevertheless, C90 remains topical here,
and in C90 (sans TCs) the behaviour in question is, and will always
remain, implementation-defined.
True, but the flaw is that there are implementations on which the
behavior cannot reasonably be defined (unless the definition says
"This can yield arbitrary results that can blow up in your face").

--
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"
Aug 16 '07 #14

P: n/a
In article <11**********************@q3g2000prf.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
>Well, you aren't allowed to do that. Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */
No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 16 '07 #15

P: n/a
Richard Tobin wrote:
Old Wolf <ol*****@inspire.net.nzwrote:
>>>Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
>Well, you aren't allowed to do that. Would youalso say that
an int is not typesafe because you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

No, I would say that casts aren't type-safe. Casts and unions
are two of the ways to have objects treated as the wrong type.
Apart from variadic function parameters, such as printf, most casts
are errors. I include unnecessary as an error.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Aug 16 '07 #16

P: n/a
On Thu, 16 Aug 2007 00:35:19 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Old Wolf said:
>On Aug 15, 1:17 pm, "Scott Fluhrer" <sfluh...@ix.netcom.comwrote:
>>"Chad" <cdal...@gmail.comwrote in message

Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */

Well, you aren't allowed to do that.

False.
Too strong.
>The behaviour is implementation-defined in C90, and undefined in
C99. Taking advantage of either behaviour is *not* forbidden,
In C99, its forbidden in the same sense that much of what we discuss
here as 'forbidden' or 'illegal' is.
--
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
Aug 16 '07 #17

P: n/a
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <11**********************@q3g2000prf.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>Now, how is it possible to violate type safety in Unions?

z.d = 42.7;
printf( "%d\n", z.i ); /* Oops */
>>Well, you aren't allowed to do that. Would you
also say that an int is not typesafe because
you can write:

int x = 10;
printf("%f", *(double *)&x); /* oops */

No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.
Not all casts are type-unsafe. A cast specifies a *conversion*; it
doesn't generally interpret an object of one type as if it were an
object of another type.

Pointer casts are potentially type-unsafe. Numeric casts merely
convert values.

--
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"
Aug 16 '07 #18

P: n/a
Keith Thompson wrote:
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[ snip ]
>No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.

Not all casts are type-unsafe. A cast specifies a *conversion*; it
doesn't generally interpret an object of one type as if it were an
object of another type.
A cast is an explicit conversion of a value from one type to another,
preserving value where possible. It has nothing to do with objects at all.
Pointer casts are potentially type-unsafe. Numeric casts merely
convert values.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Aug 16 '07 #19

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>>Well, you aren't allowed to do that. Would you
also say that an int is not typesafe because
you can write:
>> int x = 10;
printf("%f", *(double *)&x); /* oops */
>No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.
>Not all casts are type-unsafe.
True, but the point is that in the code above it is the cast that
violates type-safety, not the int as (rhetorically) suggested.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 16 '07 #20

P: n/a
Joe Wright <jo********@comcast.netwrites:
Keith Thompson wrote:
>ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[ snip ]
>>No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.
Not all casts are type-unsafe. A cast specifies a *conversion*; it
doesn't generally interpret an object of one type as if it were an
object of another type.
A cast is an explicit conversion of a value from one type to another,
preserving value where possible. It has nothing to do with objects at
all.
Right, drop the word "generally" above.
>Pointer casts are potentially type-unsafe. Numeric casts merely
convert values.
Even pointer casts aren't *directly* type-unsafe, but they enable you
to do type-unsafe things with the results.

--
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"
Aug 16 '07 #21

P: n/a
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>>>Well, you aren't allowed to do that. Would you
also say that an int is not typesafe because
you can write:
>>> int x = 10;
printf("%f", *(double *)&x); /* oops */
>>No, I would say that casts aren't type-safe. Casts and unions are two
of the ways to have objects treated as the wrong type.
>>Not all casts are type-unsafe.

True, but the point is that in the code above it is the cast that
violates type-safety, not the int as (rhetorically) suggested.
Agreed.

Just to pound once more on the greasy spot on the ground that was once
a dead horse 8-)}, I was responding to the "casts aren't type-safe"
remark, which seemed overly general.

--
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"
Aug 17 '07 #22

This discussion thread is closed

Replies have been disabled for this discussion.