Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > bitwise on float

Reply
Thread Tools

bitwise on float

 
 
Richard Heathfield
Guest
Posts: n/a
 
      05-21-2007
[Not much snipping, I'm afraid - I prefer to snip when possible, but
here it seems unwise.]

Keith Thompson said:

> Richard Heathfield <(E-Mail Removed)> writes:
>> none said:
>>> Keith Thompson wrote:
>>>> Strictly speaking, storing a value in one member of a union and
>>>> reading another member is not permitted. In practice, it's likely
>>>> to work, and what you're doing is pretty much inherently
>>>> non-portable anyway.
>>>
>>> Sorry to hijack the thread, but this is precisely what I use unions
>>> for. If this is not allowed, then what is the point of unions?

>>
>> It *is* allowed - Keith is wrong about that, at least in C90. But its
>> effect is implementation-defined.

>
> I based my statement on the following in the C99 standard:


I won't argue about C99, specifically because I couldn't find wording in
the C99 Standard to match the C89 wording (as I hinted above, although
I actually said C90 when I should have said C89 - I only have a late
C89 draft). I'm sure of my ground ifF the final C90 Standard agrees
with the C89 draft.

>
> C99 6.7.2.1p14:
>
> The size of a union is sufficient to contain the largest of its
> members. The value of at most one of the members can be stored in
> a union object at any time. A pointer to a union object, suitably
> converted, points to each of its members (or if a member is a
> bitfield, then to the unit in which it resides), and vice versa.
>
> C90 6.5.2.1 has identical wording.
>
> I infer from the second sentence that the standard does not define the
> behavior of reading a union member other than the one last stored,


I won't even argue with /that/, but see below.

> except:
>
> C99 6.5.2.3p5:
>

<CIS wording snipped, at least!>
>
> Chances are that you're right, and I'm missing something. Can you
> provide C&V?


Sure. Hang on...

"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."

That's 3.3.2.3 in C89. So no, the Standard doesn't define the behaviour,
but it requires the /implementation/ to define the behaviour, and
that's not what we normally understand by "undefined", any more than
the value of CHAR_BIT is undefined.

Nevertheless, you can still prove me wrong if you can show... well, it's
hard to show an absence, isn't it? But if you say that the C89 late
draft wording cited above is missing from the C90 spec, I'll certainly
take your word for it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      05-21-2007
Richard Heathfield <(E-Mail Removed)> writes:
> [Not much snipping, I'm afraid - I prefer to snip when possible, but
> here it seems unwise.]
>
> Keith Thompson said:
>
>> Richard Heathfield <(E-Mail Removed)> writes:
>>> none said:
>>>> Keith Thompson wrote:
>>>>> Strictly speaking, storing a value in one member of a union and
>>>>> reading another member is not permitted. In practice, it's likely
>>>>> to work, and what you're doing is pretty much inherently
>>>>> non-portable anyway.
>>>>
>>>> Sorry to hijack the thread, but this is precisely what I use unions
>>>> for. If this is not allowed, then what is the point of unions?
>>>
>>> It *is* allowed - Keith is wrong about that, at least in C90. But its
>>> effect is implementation-defined.

>>
>> I based my statement on the following in the C99 standard:

>
> I won't argue about C99, specifically because I couldn't find wording in
> the C99 Standard to match the C89 wording (as I hinted above, although
> I actually said C90 when I should have said C89 - I only have a late
> C89 draft). I'm sure of my ground ifF the final C90 Standard agrees
> with the C89 draft.


It does.

>> C99 6.7.2.1p14:
>>
>> The size of a union is sufficient to contain the largest of its
>> members. The value of at most one of the members can be stored in
>> a union object at any time. A pointer to a union object, suitably
>> converted, points to each of its members (or if a member is a
>> bitfield, then to the unit in which it resides), and vice versa.
>>
>> C90 6.5.2.1 has identical wording.
>>
>> I infer from the second sentence that the standard does not define the
>> behavior of reading a union member other than the one last stored,

>
> I won't even argue with /that/, but see below.
>
>> except:
>>
>> C99 6.5.2.3p5:
>>

> <CIS wording snipped, at least!>
>>
>> Chances are that you're right, and I'm missing something. Can you
>> provide C&V?

>
> Sure. Hang on...
>
> "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."


Yes, that's what I was missing.

> That's 3.3.2.3 in C89. So no, the Standard doesn't define the behaviour,
> but it requires the /implementation/ to define the behaviour, and
> that's not what we normally understand by "undefined", any more than
> the value of CHAR_BIT is undefined.


Agreed.

> Nevertheless, you can still prove me wrong if you can show... well, it's
> hard to show an absence, isn't it? But if you say that the C89 late
> draft wording cited above is missing from the C90 spec, I'll certainly
> take your word for it.


C90 has the same wording. My PDF copy of the C90 standard is
difficult to search and to copy-and-paste, but with C&V I can find the
passage (it's 6.3.2.3). Some typos may remain.

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 (41). One special guarantee
is made in order to simplify the use of unions: If a union
contains several structures that share a common initial sequence
(see below), and if the union object currently contains one of
these structures, it is permitted to inspect the common initial
part of any of them. Two structures share a _common initial
sequence_ if corresponding members have compatible types (and, for
bit-fields, the same widths) for a sequence of one or more initial
members.

(A straight copy-and-paste contains the phrase "Two structures share a
wmnzorl birid sey~~r~e ..."; somebody's OCR software didn't like
italics.)

Footnote 41 says:

The "byte orders" for scalar types are invisible to isolated
programs that do not indulge in type punning (for example, by
assigning to one member of a union and inspecting the storage by
accessing another member that is an appropriately sized array of
character type), but must be accounted for when conforming to
externally imposed storage layouts.

The C99 standard drops the sentence "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." and the footnote.

Interestingly, the definition of "implementation-defined behavior"
changed from C90 to C99, and I suspect that's why that sentence was
dropped.

In C90:

implementation-defined behavior

Behavior, forr a correct program construct and correct data, that
depends on the characteristics of the implementation and that each
implementation shall document

In C99:

implementation-defined behavior

unspecified behavior where each implementation documents how the
choice is made

unspecified behavior

use of an unspecified value, or other behavior where this
International Standard provides two or more possibilities and
imposes no further requirements on which is chosen in any instance

So C90, by making reading a non-current union member
implementation-defined, merely requires the implementation to document
the behavior. To meet the C99 definition of "implementation-defined
behavior", the standard would have to specify two or more
possibilities from which each implementation could choose.

Unless there's yet again something else that I'm missing, I think that
C99 has dropped the idea that type punning can be done without
invoking outright undefined behavior, except for character types and
common initial sequences. But it's still almost certain to "work" for
almost all real-world implementations. IMHO, it's such a common
practice that the C99 standard should have said more about it.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      05-22-2007
Keith Thompson said:

> (A straight copy-and-paste contains the phrase "Two structures share a
> wmnzorl birid sey~~r~e ..."; somebody's OCR software didn't like
> italics.)


No no no, that's normative! It was obviously a response to a DR
zubmitted by zomeone from Zummerzet. Translation: "Two structures share
a worzel-bird, see?"

I trust that this clears up any mystery.

> Interestingly, the definition of "implementation-defined behavior"
> changed from C90 to C99, and I suspect that's why that sentence was
> dropped.


It's entirely possible, in which case C90 will certainly remain popular
amongst those who enjoy a good type-pun.

<snip>

> Unless there's yet again something else that I'm missing, I think that
> C99 has dropped the idea that type punning can be done without
> invoking outright undefined behavior, except for character types and
> common initial sequences.


And yet it could be done in C90. And if it can be done by the ancients,
surely it shouldn't be too big a deal for the moderns?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-22-2007
Richard Heathfield <(E-Mail Removed)> writes:
> Keith Thompson said:

[...]
>> Unless there's yet again something else that I'm missing, I think that
>> C99 has dropped the idea that type punning can be done without
>> invoking outright undefined behavior, except for character types and
>> common initial sequences.

>
> And yet it could be done in C90. And if it can be done by the ancients,
> surely it shouldn't be too big a deal for the moderns?


Built any pyramids lately?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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"
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      05-22-2007
Keith Thompson said:

> Richard Heathfield <(E-Mail Removed)> writes:
>> Keith Thompson said:

> [...]
>>> Unless there's yet again something else that I'm missing, I think
>>> that C99 has dropped the idea that type punning can be done without
>>> invoking outright undefined behavior, except for character types and
>>> common initial sequences.

>>
>> And yet it could be done in C90. And if it can be done by the
>> ancients, surely it shouldn't be too big a deal for the moderns?

>
> Built any pyramids lately?


Yes. It wasn't easy, but nothing worthwhile ever is. I am glad to report
that it performs fully according to spec - I will never have to buy
another razor blade.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
 
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
float to string to float, with first float == second float Carsten Fuchs C++ 45 10-08-2009 09:47 AM
retrieve bitwise float representation Ulrich Eckhardt Python 3 06-11-2009 01:20 PM
Bitwise Operations on double, float siryuhan@gmail.com C++ 4 05-18-2007 11:42 AM
need code to convert float format to internal java float format which is kept in 4 bytes integer Andy Java 7 05-10-2004 09:26 PM
Re: float->byte->float is same with original float image. why float->ubyte->float is different??? bd C Programming 0 07-07-2003 12:09 AM



Advertisments