Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Type punning

Reply
Thread Tools

Type punning

 
 
Skarmander
Guest
Posts: n/a
 
      11-30-2005
This:
#include <stdint.h>

union r_float {
float f;
uint32_t i;
};

/* .. */
float f;
uint32_t i;
union r_float ra;

/* .. */
ra.f = f;
i = ra.i;

depends only on implementation-defined aspects, right? That is, if I know
uint32_t exists and the sizes of the objects are identical, will 'i' and 'f'
have identical bit patterns after the assignments? Similarly, will the same
hold for:

ra.i = i;
f = ra.f;

if I know the bit pattern of 'i' is not a trap representation for 'float'?

S.
 
Reply With Quote
 
 
 
 
Robert Gamble
Guest
Posts: n/a
 
      11-30-2005
Skarmander wrote:
> This:
> #include <stdint.h>
>
> union r_float {
> float f;
> uint32_t i;
> };
>
> /* .. */
> float f;
> uint32_t i;
> union r_float ra;
>
> /* .. */
> ra.f = f;
> i = ra.i;
>
> depends only on implementation-defined aspects, right? That is, if I know
> uint32_t exists and the sizes of the objects are identical, will 'i' and 'f'
> have identical bit patterns after the assignments? Similarly, will the same
> hold for:


It is not guaranteed by the Standard that objects of the same size will
overlap bit for bit. If your implementation does guarantee that they
will and you know that the objects are the same size and that the
values specified for one member represent a valid value for the other
member then there is no undefined behavior as far as I can see.

> ra.i = i;
> f = ra.f;
>
> if I know the bit pattern of 'i' is not a trap representation for 'float'?


Same as above.

Robert Gamble

 
Reply With Quote
 
 
 
 
Michael Mair
Guest
Posts: n/a
 
      11-30-2005
Skarmander wrote:
> This:
> #include <stdint.h>
>
> union r_float {
> float f;
> uint32_t i;
> };
>
> /* .. */
> float f;
> uint32_t i;
> union r_float ra;
>
> /* .. */
> ra.f = f;
> i = ra.i;
>
> depends only on implementation-defined aspects, right? That is, if I
> know uint32_t exists and the sizes of the objects are identical, will
> 'i' and 'f' have identical bit patterns after the assignments?
> Similarly, will the same hold for:
>
> ra.i = i;
> f = ra.f;
>
> if I know the bit pattern of 'i' is not a trap representation for 'float'?


As long as there are no padding bits whatsoever or if the padding bits
are the same.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      11-30-2005
Michael Mair wrote:
> Skarmander wrote:
>> This:
>> #include <stdint.h>
>>
>> union r_float {
>> float f;
>> uint32_t i;
>> };
>>
>> /* .. */
>> float f;
>> uint32_t i;
>> union r_float ra;
>>
>> /* .. */
>> ra.f = f;
>> i = ra.i;
>>
>> depends only on implementation-defined aspects, right? That is, if I
>> know uint32_t exists and the sizes of the objects are identical, will
>> 'i' and 'f' have identical bit patterns after the assignments?
>> Similarly, will the same hold for:
>>
>> ra.i = i;
>> f = ra.f;
>>
>> if I know the bit pattern of 'i' is not a trap representation for
>> 'float'?

>
> As long as there are no padding bits whatsoever or if the padding bits
> are the same.
>

uint32_t has no padding bits, by definition; for a 'float' "padding bits"
are not defined, since the entire representation is unspecified, but this
should be covered by "no trap representations".

S.
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      11-30-2005
Skarmander wrote:
> Michael Mair wrote:
>
>> Skarmander wrote:
>>
>>> This:
>>> #include <stdint.h>
>>>
>>> union r_float {
>>> float f;
>>> uint32_t i;
>>> };
>>>
>>> /* .. */
>>> float f;
>>> uint32_t i;
>>> union r_float ra;
>>>
>>> /* .. */
>>> ra.f = f;
>>> i = ra.i;
>>>
>>> depends only on implementation-defined aspects, right? That is, if I
>>> know uint32_t exists and the sizes of the objects are identical, will
>>> 'i' and 'f' have identical bit patterns after the assignments?
>>> Similarly, will the same hold for:
>>>
>>> ra.i = i;
>>> f = ra.f;
>>>
>>> if I know the bit pattern of 'i' is not a trap representation for
>>> 'float'?

>>
>>
>> As long as there are no padding bits whatsoever or if the padding bits
>> are the same.
>>

> uint32_t has no padding bits, by definition;


You are right, of course.

> for a 'float' "padding
> bits" are not defined, since the entire representation is unspecified,
> but this should be covered by "no trap representations".


Padding bits may be harmless, trap representations are not, cf
C99, 6.2.6.2. In addition, trap representations may not depend on
padding bits at all.
As one does not need 32 bits to meet the requirements for float,
padding bits are possible. There is AFAICS no rule in the standard
that padding bits have to stay the same all the time, so the
implementation may change the representation to help SETI@home
with spare bits for all I know.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      11-30-2005
Michael Mair wrote:
<snip>
>> for a 'float' "padding bits" are not defined, since the entire
>> representation is unspecified, but this should be covered by "no trap
>> representations".

>
> Padding bits may be harmless, trap representations are not, cf
> C99, 6.2.6.2. In addition, trap representations may not depend on
> padding bits at all.


Yes. The intent is that the representation of 'float's is known, at least
well enough to avoid trap representations.

> As one does not need 32 bits to meet the requirements for float,
> padding bits are possible. There is AFAICS no rule in the standard
> that padding bits have to stay the same all the time,


That is true, but it would take a DeathStation 9000 to have floats where
xpadding bits can change at whim *and* cause trap representations if a
previously observed pattern is stored. That's not to say such hardware
cannot exist, but I'll be content mentioning in a footnote that you are
kindly not to compile the program on such platforms.

> so the implementation may change the representation to help SETI@home
> with spare bits for all I know.
>

That would be a fascinating application and I for one would love to see it,
but I think we can discount that possibility.

S.
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      11-30-2005
On 2005-11-30, Skarmander <> wrote:
> Michael Mair wrote:
> <snip>
>>> for a 'float' "padding bits" are not defined, since the entire
>>> representation is unspecified, but this should be covered by "no trap
>>> representations".

>>
>> Padding bits may be harmless, trap representations are not, cf
>> C99, 6.2.6.2. In addition, trap representations may not depend on
>> padding bits at all.

>
> Yes. The intent is that the representation of 'float's is known, at least
> well enough to avoid trap representations.
>
>> As one does not need 32 bits to meet the requirements for float,
>> padding bits are possible. There is AFAICS no rule in the standard
>> that padding bits have to stay the same all the time,

>
> That is true, but it would take a DeathStation 9000 to have floats where
> xpadding bits can change at whim *and* cause trap representations if a
> previously observed pattern is stored. That's not to say such hardware
> cannot exist, but I'll be content mentioning in a footnote that you are
> kindly not to compile the program on such platforms.
>
>> so the implementation may change the representation to help SETI@home
>> with spare bits for all I know.
>>

> That would be a fascinating application and I for one would love to see it,
> but I think we can discount that possibility.
>
> S.


What about memcpy in that case? to an unsigned char array and back - i
think that if that could cause a later read as a float to become a trap
representation it _would_ render the implementation non-conforming [so,
no DS9K]
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      11-30-2005
Jordan Abel wrote:
> On 2005-11-30, Skarmander <> wrote:
>> Michael Mair wrote:
>> <snip>
>>>> for a 'float' "padding bits" are not defined, since the entire
>>>> representation is unspecified, but this should be covered by "no trap
>>>> representations".
>>> Padding bits may be harmless, trap representations are not, cf
>>> C99, 6.2.6.2. In addition, trap representations may not depend on
>>> padding bits at all.

>> Yes. The intent is that the representation of 'float's is known, at least
>> well enough to avoid trap representations.
>>
>>> As one does not need 32 bits to meet the requirements for float,
>>> padding bits are possible. There is AFAICS no rule in the standard
>>> that padding bits have to stay the same all the time,

>> That is true, but it would take a DeathStation 9000 to have floats where
>> xpadding bits can change at whim *and* cause trap representations if a
>> previously observed pattern is stored. That's not to say such hardware
>> cannot exist, but I'll be content mentioning in a footnote that you are
>> kindly not to compile the program on such platforms.
>>
>>> so the implementation may change the representation to help SETI@home
>>> with spare bits for all I know.
>>>

>> That would be a fascinating application and I for one would love to see it,
>> but I think we can discount that possibility.
>>

>
> What about memcpy in that case? to an unsigned char array and back - i
> think that if that could cause a later read as a float to become a trap
> representation it _would_ render the implementation non-conforming [so,
> no DS9K]


Hm. I've just tested it on gcc and it is actually capable of turning this
into a no-op, so a memcpy() would be a maximally portable solution that at
least some compilers could handle perfectly.

On the other hand, if the platform does *not* optimize away these memcpy()
calls, you take a significant performance hit for little appreciable gain;
that is, the ability to use this code unmodified even if float uses demonic
padding bits. (Not just any padding bits, mind you. Demonic ones.) And then
you still have to see whether platforms with such problems actually get the
memcpy() right, too -- at this microlevel, it's no good to be able to thumb
your nose at a non-conforming platform if your code still won't work.

The best solution is probably still to use a simple reinterpreting through a
union, with a clear explanation of when this can and cannot be expected to
work, and offering the more portable but possibly unacceptably slow
solutions as an alternative.

S.
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      12-01-2005
On 2005-11-30, Skarmander <> wrote:
> On the other hand, if the platform does *not* optimize away these memcpy()
> calls, you take a significant performance hit for little appreciable gain;
> that is, the ability to use this code unmodified even if float uses demonic
> padding bits. (Not just any padding bits, mind you. Demonic ones.)


My point is that demonic padding bits are illegal according to the
standard for this reason.
 
Reply With Quote
 
Skarmander
Guest
Posts: n/a
 
      12-01-2005
Jordan Abel wrote:
> On 2005-11-30, Skarmander <> wrote:
>> On the other hand, if the platform does *not* optimize away these memcpy()
>> calls, you take a significant performance hit for little appreciable gain;
>> that is, the ability to use this code unmodified even if float uses demonic
>> padding bits. (Not just any padding bits, mind you. Demonic ones.)

>
> My point is that demonic padding bits are illegal according to the
> standard for this reason.


I don't see how that follows. An implementation could work around its
demonic padding bits in calls to memcpy() (or in general if objects with
them are aliased through char types), and as you point out, the standard
would in fact require it to. But if I access a float in a union through a
member of type uint32_t, I am not similarly protected, and the demonic
padding bits could take wing and strafe me.

There might be a longer chain of reasoning with definitions in the standard
that actually prohibit DPBs, but I don't think the direct approach you used
works.

S.
 
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
Type Punning kid joe C Programming 3 05-18-2009 03:44 AM
type punning goodfella C++ 9 09-05-2008 08:33 PM
type-punning? j.j.fishbat@gmail.com C Programming 15 05-06-2008 10:49 PM
Type punning, code reordering and overloaded operator new() withcustom allocator chris42f@gmail.com C++ 0 11-23-2007 09:49 AM
Type-punning / casting problem Phil Endecott C++ 20 09-18-2007 07:40 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57