Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > structure and union queries

Reply
Thread Tools

structure and union queries

 
 
Barry Schwarz
Guest
Posts: n/a
 
      04-09-2009
On Wed, 08 Apr 2009 18:26:39 -0400, Joe Wright
<(E-Mail Removed)> wrote:

>(E-Mail Removed) wrote:
>> jameskuyper <(E-Mail Removed)> wrote:
>>> Any attempt to use the value of S.f2 or s.i at this point in the
>>> program has undefined behavior. The only member of a union that you
>>> can safely read is the member that was last written to.

>>
>> That was the rule in C90, but the rules in C99 recognize what really
>> happens -- the existing bits are reinterpreted in the other type. Since
>> f2 has the same type as the member that was last written to, the
>> behavior of accessing it is completely defined. Accessing i is a bit
>> more fluid; since the types are different, the existing bits may or may
>> not be a valid representation. If they are, the behavior is well
>> defined but the resulting value is unspecified. If not, all bets are
>> off and you still get undefined behavior.

>
>I still don't get it.
>
> union s {
> float f;
> int i;
> };
>
> union s S;
> S.f = 66;
>
>The union S is essentially a 32-bit object with two names. The above
>assignment will set the bits of S like this..
>
>01000010 10000100 00000000 00000000


On my system the bits will be
01000010 01100110 00000000 00000000
My system uses hex floating point, not binary, so the leading bit in a
normalized mantissa need not be 1.

>
>If I then printf("%d\n", S.i) I will get..
>
>1115947008


You appear to have a big endian system. What abut the poor people
with little endian ones? Will they see 33860?

I would probably get 1113980928 but that still doesn't alter the fact
that the behavior is undefined.

>
>and then printf("%f\n", S.f) I will get..
>
>66.000000
>
>I read S.i first, after assigning to S.f. Assuming float and int are
>both 32 bits, what about the foregoing is undefined behavior? What can
>possibly be wrong with it?


The fact that the C90 standard says it is undefined. The compiler is
not even obligated to generate the "expected" code, even though almost
all do.

It is not much different than passing overlapping fields to strcpy or
memcpy. On most systems it will do the "expected." It is still
undefined.

--
Remove del for email
 
Reply With Quote
 
 
 
 
nick_keighley_nospam@hotmail.com
Guest
Posts: n/a
 
      04-09-2009
On 9 Apr, 01:20, CBFalconer <(E-Mail Removed)> wrote:
> Joe Wright wrote:


> > I still don't get it.


[stuff to do with unions]


> > * *union s {
> > * * *float f;
> > * * *int i;
> > * *};

>
> > * *union s S;
> > * *S.f = 66;

>
> > The union S is essentially a 32-bit object with two names. The
> > above assignment will set the bits of S like this..

>
> > 01000010 10000100 00000000 00000000

>
> > If I then printf("%d\n", S.i) I will get..

>
> > 1115947008

>
> > and then printf("%f\n", S.f) I will get..

>
> > 66.000000

>
> > I read S.i first, after assigning to S.f. Assuming float and int
> > are both 32 bits, what about the foregoing is undefined behavior?


the representations of int and float are different.
and assuming both are 32-bits is a big assumption.

> > What can possibly be wrong with it?


Signalling NaN


> The 'wrong' thing is some idiot assuming that the access to S.f
> magically reorganizes the bits in S to form the integer 66. *There
> are more and more of these idiots around, who have no idea what
> really goes on, and who depend on the use of 'SHAZAM'.


A bit unfair, I think. Floating point has some non-intuitive
properties
and with unions you are getting pretty chummy with the hardware.

At least this guy is asking the questions.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      04-09-2009
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:
> On 9 Apr, 01:20, CBFalconer <(E-Mail Removed)> wrote:
>> Joe Wright wrote:

[...]
>> > * *union s {
>> > * * *float f;
>> > * * *int i;
>> > * *};

>>
>> > * *union s S;
>> > * *S.f = 66;

[...]
>> > What can possibly be wrong with it?

>
> Signalling NaN

[...]

Signalling NaNs aren't an issue in this particular case. The value 66
(converted to 66.0f) was stored in S.f. The problem is that S.i could
contain a trap representation, either because the bit pattern used to
represent 66.0f happens to be a trap representation for type int, or
because int is bigger than float and the remaining bits of S.i are
garbage.

(In practice, most implementations don't have trap representations for
type int, but you can't assume that in portable code.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      04-09-2009
CBFalconer wrote:
> Joe Wright wrote:
> ... snip ...
>> I still don't get it.
>>
>> union s {
>> float f;
>> int i;
>> };
>>
>> union s S;
>> S.f = 66;
>>
>> The union S is essentially a 32-bit object with two names. The
>> above assignment will set the bits of S like this..
>>
>> 01000010 10000100 00000000 00000000
>>
>> If I then printf("%d\n", S.i) I will get..
>>
>> 1115947008
>>
>> and then printf("%f\n", S.f) I will get..
>>
>> 66.000000
>>
>> I read S.i first, after assigning to S.f. Assuming float and int
>> are both 32 bits, what about the foregoing is undefined behavior?
>> What can possibly be wrong with it?

>
> The 'wrong' thing is some idiot assuming that the access to S.f
> magically reorganizes the bits in S to form the integer 66. There


He's said nothing to suggest that he's expecting a magical
reorganization. In one of the earlier messages which are invisible to
you, he has very explicitly stated that he expects the member with the
type that is different from the one most recently written to have a
"garbage" value, by which he apparently means a value which has a
relationship to the value written that can only be predicted by a
complicated process that depends upon the precise details of how both
'int' and 'float' are represented, and as such is highly non-portable.

What he didn't understand was how the consequences could be anything
worse than a garbage value. He was apparently unfamiliar with the
possibility of trap representations, and couldn't imagine any of the
more exotic ways in which the code could fail.
 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      04-09-2009
jameskuyper <(E-Mail Removed)> wrote:
>
> Even on platforms without such exotic hardware, the fact that the
> standard says that this has undefined behavior indirectly opens up
> other possible failure modes. For instance, it gives implementations
> permission to perform optimizations that would otherwise be illegal.


Not in C99.
--
Larry Jones

My "C-" firmly establishes me on the cutting edge of the avant-garde.
-- Calvin
 
Reply With Quote
 
jameskuyper
Guest
Posts: n/a
 
      04-09-2009
(E-Mail Removed) wrote:
> jameskuyper <(E-Mail Removed)> wrote:
> >
> > Even on platforms without such exotic hardware, the fact that the
> > standard says that this has undefined behavior indirectly opens up
> > other possible failure modes. For instance, it gives implementations
> > permission to perform optimizations that would otherwise be illegal.

>
> Not in C99.


Sorry - I should have clarified that I was referring to C90. You've
already pointed out that distinction, and I failed to acknowledge it.

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      04-09-2009
(E-Mail Removed) wrote:
> CBFalconer <(E-Mail Removed)> wrote:
>> Joe Wright wrote:
>>

> [stuff to do with unions]
>
>>> union s {
>>> float f;
>>> int i;
>>> };
>>>
>>> union s S;
>>> S.f = 66;
>>>
>>> The union S is essentially a 32-bit object with two names. The
>>> above assignment will set the bits of S like this..
>>>
>>> 01000010 10000100 00000000 00000000
>>>
>>> If I then printf("%d\n", S.i) I will get..
>>>
>>> 1115947008
>>>
>>> and then printf("%f\n", S.f) I will get..
>>>
>>> 66.000000
>>>
>>> I read S.i first, after assigning to S.f. Assuming float and int
>>> are both 32 bits, what about the foregoing is undefined behavior?

>

.... snip ...
>
>> The 'wrong' thing is some idiot assuming that the access to S.f
>> magically reorganizes the bits in S to form the integer 66. There
>> are more and more of these idiots around, who have no idea what
>> really goes on, and who depend on the use of 'SHAZAM'.

>
> A bit unfair, I think. Floating point has some non-intuitive
> properties and with unions you are getting pretty chummy with the
> hardware. At least this guy is asking the questions.


You have a point. However, to me, the fact that two items occupy
the same space and can represent different sets of values screams
that "the format is different".

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      04-10-2009
CBFalconer wrote:
> (E-Mail Removed) wrote:
>> CBFalconer <(E-Mail Removed)> wrote:
>>> Joe Wright wrote:
>>>

>> [stuff to do with unions]
>>
>>>> union s {
>>>> float f;
>>>> int i;
>>>> };
>>>>
>>>> union s S;
>>>> S.f = 66;
>>>>
>>>> The union S is essentially a 32-bit object with two names. The
>>>> above assignment will set the bits of S like this..
>>>>
>>>> 01000010 10000100 00000000 00000000
>>>>
>>>> If I then printf("%d\n", S.i) I will get..
>>>>
>>>> 1115947008
>>>>
>>>> and then printf("%f\n", S.f) I will get..
>>>>
>>>> 66.000000
>>>>
>>>> I read S.i first, after assigning to S.f. Assuming float and int
>>>> are both 32 bits, what about the foregoing is undefined behavior?

> ... snip ...
>>> The 'wrong' thing is some idiot assuming that the access to S.f
>>> magically reorganizes the bits in S to form the integer 66. There
>>> are more and more of these idiots around, who have no idea what
>>> really goes on, and who depend on the use of 'SHAZAM'.

>> A bit unfair, I think. Floating point has some non-intuitive
>> properties and with unions you are getting pretty chummy with the
>> hardware. At least this guy is asking the questions.

>
> You have a point. However, to me, the fact that two items occupy
> the same space and can represent different sets of values screams
> that "the format is different".


Yes, but he said nothing to suggest that he was unaware of that fact. He
in no way implied that he expected anything like the magical
reorganization you refer to. He just expected that the bits that were
written as a floating point value would be reinterpreted as a
representing a very different integer value, with no unexpected side
effects.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      04-11-2009
James Kuyper wrote:
> CBFalconer wrote:
>> (E-Mail Removed) wrote:
>>> CBFalconer <(E-Mail Removed)> wrote:
>>>> Joe Wright wrote:
>>>>
>>> [stuff to do with unions]
>>>
>>>>> union s {
>>>>> float f;
>>>>> int i;
>>>>> };
>>>>>
>>>>> union s S;
>>>>> S.f = 66;
>>>>>
>>>>> The union S is essentially a 32-bit object with two names. The
>>>>> above assignment will set the bits of S like this..
>>>>>
>>>>> 01000010 10000100 00000000 00000000
>>>>>
>>>>> If I then printf("%d\n", S.i) I will get..
>>>>>
>>>>> 1115947008
>>>>>
>>>>> and then printf("%f\n", S.f) I will get..
>>>>>
>>>>> 66.000000
>>>>>
>>>>> I read S.i first, after assigning to S.f. Assuming float and int
>>>>> are both 32 bits, what about the foregoing is undefined behavior?

>>
>> ... snip ...
>>
>>>> The 'wrong' thing is some idiot assuming that the access to S.f
>>>> magically reorganizes the bits in S to form the integer 66.
>>>> There are more and more of these idiots around, who have no
>>>> idea what really goes on, and who depend on the use of 'SHAZAM'.
>>>
>>> A bit unfair, I think. Floating point has some non-intuitive
>>> properties and with unions you are getting pretty chummy with
>>> the hardware. At least this guy is asking the questions.

>>
>> You have a point. However, to me, the fact that two items occupy
>> the same space and can represent different sets of values screams
>> that "the format is different".

>
> Yes, but he said nothing to suggest that he was unaware of that
> fact. He in no way implied that he expected anything like the
> magical reorganization you refer to. He just expected that the
> bits that were written as a floating point value would be
> reinterpreted as a representing a very different integer value,
> with no unexpected side effects.


Any such would require storage of the actual stored format, and the
requested format. This can be an unlimited number of
possibilities. Very minor thinking can infer the magic
requirement, IMO. Since all objects are typed, casts provide that
sort of information.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      04-11-2009
CBFalconer wrote:
> James Kuyper wrote:
>> CBFalconer wrote:
>>> (E-Mail Removed) wrote:
>>>> CBFalconer <(E-Mail Removed)> wrote:
>>>>> Joe Wright wrote:
>>>>>
>>>> [stuff to do with unions]
>>>>
>>>>>> union s {
>>>>>> float f;
>>>>>> int i;
>>>>>> };
>>>>>>
>>>>>> union s S;
>>>>>> S.f = 66;
>>>>>>
>>>>>> The union S is essentially a 32-bit object with two names. The
>>>>>> above assignment will set the bits of S like this..
>>>>>>
>>>>>> 01000010 10000100 00000000 00000000
>>>>>>
>>>>>> If I then printf("%d\n", S.i) I will get..
>>>>>>
>>>>>> 1115947008
>>>>>>
>>>>>> and then printf("%f\n", S.f) I will get..
>>>>>>
>>>>>> 66.000000
>>>>>>
>>>>>> I read S.i first, after assigning to S.f. Assuming float and int
>>>>>> are both 32 bits, what about the foregoing is undefined behavior?
>>> ... snip ...
>>>
>>>>> The 'wrong' thing is some idiot assuming that the access to S.f
>>>>> magically reorganizes the bits in S to form the integer 66.
>>>>> There are more and more of these idiots around, who have no
>>>>> idea what really goes on, and who depend on the use of 'SHAZAM'.
>>>> A bit unfair, I think. Floating point has some non-intuitive
>>>> properties and with unions you are getting pretty chummy with
>>>> the hardware. At least this guy is asking the questions.
>>> You have a point. However, to me, the fact that two items occupy
>>> the same space and can represent different sets of values screams
>>> that "the format is different".

>> Yes, but he said nothing to suggest that he was unaware of that
>> fact. He in no way implied that he expected anything like the
>> magical reorganization you refer to. He just expected that the
>> bits that were written as a floating point value would be
>> reinterpreted as a representing a very different integer value,
>> with no unexpected side effects.

>
> Any such would require storage of the actual stored format, and the
> requested format.


As the result depends only upon the bits that were stored, and not upon
the format that was used to store them, why would you need to store that
format?

The requested format is determined by the union member used to refer to
the object, there is no need to store this information anywhere, except
in the sense that the sequence of instructions in the executable program
that perform the retrieval can be considered as storing information
about which format that is.

> ... This can be an unlimited number of
> possibilities. ...


No, in a union with two members, there's only two possibilities; only
the one that corresponds to the member you are currently referring to
actually matters at any given point.

> ... Very minor thinking can infer the magic
> requirement, IMO.


What's magical about writing the contents of a floating point register
to RAM, then reading the contents of that ram into an integer register?
I get the impression that you are still of the mistaken opinion that he
expressed an expectation that the integer he retrieved would have the
same numerical values as the floating point number he stored. He
expressed no such expectation.

> ... Since all objects are typed, ...


That is not true. Dynamically allocated memory constitutes an object
that has no declared type, and no effective type. It can acquire an
effective type by being written to using an lvalue that is not of
character type, or by a memcpy() from another object that does have an
effective type. But until that happens, that object does not have a type
(6.5p6).

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
xslt queries in xml to SQL queries Ian Roddis Python 3 02-26-2006 06:49 PM
Nested MSAccess Union-Queries in asp d2r2 ASP General 2 12-28-2004 01:38 PM
so many queries within queries I'm confused Abby Lee ASP General 11 08-06-2004 07:56 PM
union in struct without union name Peter Dunker C Programming 2 04-26-2004 07:23 PM
map XML union to C union (and vice-versa) Matt Garman XML 1 04-25-2004 12:40 AM



Advertisments