473,387 Members | 1,464 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

An example of unions not being type safe?

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
21 3539

"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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: David | last post by:
Some developers in my group are using UNIONS to define their data types in a C++ program for an embedded system. Are there any pro and cons in doing this when you can define a CLASS to do the same...
6
by: Neil Zanella | last post by:
Hello, I would like to know whether the following C fragment is legal in standard C and behaves as intended under conforming implementations... union foo { char c; double d; };
16
by: Tim Cambrant | last post by:
Hi. I was reading up a bit on the features of C I seldom use, and I came across unions. I understand the concept, and that all the contained variables etc. share the same memory. Thus, when a new...
9
by: Neil Zanella | last post by:
Hello, Some programmers like to use a coding convention where all names of variables that are pointers start with the letter p (and sometimes even use similar conventions for strings and other...
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
2
by: Jeff Chan | last post by:
I have read the documentation from msdn to try to understanding the concept of "Type safe". Would someone give me an example of code segment illustrating what is *Non* type safe? Many Thanks,...
4
by: Brian | last post by:
I have been porting some C++ code to .net. I know C# doesn't have unions but in order to write a particular algorythm efficiently i have a need to address memory in in 2 different ways. As...
26
by: Old Wolf | last post by:
Ok, we've had two long and haphazard threads about unions recently, and I still don't feel any closer to certainty about what is permitted and what isn't. The other thread topics were "Real Life...
11
by: pereges | last post by:
Hello, can some one please guide me a little into using unions. I read about unions in K & R but I am finding it difficult to apply to my problem at hand. I want to save up some space by using...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.