Union test for endianess

M

Morris Keesan

Here, you assume that the width of unsigned is greater than CHAR_BIT.
If it is not (e.g. when sizeof(unsigned) == 1) then the shift is
undefined. I only mention it because you were aiming to be free of size
assumptions.

Good point. So we can add as a first statement in the function
if (sizeof(unsigned) == 1) return BIG_ENDIAN; /* or LITTLE_ENDIAN */
or get fancier and use rand() to return a random value, since endian-ness
is meaningless in a one-byte type.
 
S

Shao Miller

Is there any particular reason you want to use a union for such a
purpose? Casting any data pointer to unsigned char is the way mandated
by the standard to inspect individual bytes of an object.

Where is this mandated? 6.2.6.1p4 includes:

"Values stored in non-bit-field objects of any other object type
consist of n X CHAR_BIT bits, where n is the size of an object of that
type, in bytes. The value may be copied into an object of type unsigned
char [n] (e.g., by memcpy); the resulting set of bytes is called the
object representation of the value. ..."

What better way to copy the value of an 'int' into an 'unsigned
char[sizeof (int)]' than by having a union whereby there's already such
an array waiting in the same spot?

Use of a union with a [preferably 'unsigned'] 'char' (signed
considerations discussed elsethread) array which exactly overlaps some
other member appears to accomplish precisely the same thing
(inspection). The original post referred to a strategy offered in a C
FAQ, if I recall correctly.
 
J

Jens

Is there any particular reason you want to use a union for such a
purpose? Casting any data pointer to unsigned char is the way mandated
by the standard to inspect individual bytes of an object.

Where is this mandated?  6.2.6.1p4 includes:
exactly

Use of a union with a [preferably 'unsigned'] 'char' (signed
considerations discussed elsethread) array which exactly overlaps some
other member appears to accomplish precisely the same thing
(inspection).  The original post referred to a strategy offered in a C
FAQ, if I recall correctly.

Because in appendix J, J.1 unspecific behavior it lists:

- The value of a union member other than the last one stored into

So the standard clearly says that pointers to unsigned char are ok and
that for unions the implementation may decide to throw you some other
values in the face. And this is even "unspecific behavior" and not
"implementation defined", so an implementation is not even obliged to
document this or to be consistent with it.
 
S

Shao Miller

One way to test for endianess is to use a union:
Is there any particular reason you want to use a union for such a
purpose? Casting any data pointer to unsigned char is the way mandated
by the standard to inspect individual bytes of an object.

Where is this mandated? 6.2.6.1p4 includes:
"Values stored in non-bit-field objects of any other object type consist of n X CHAR_BIT bits, where n is the size of an object of that type, in bytes. The value may be copied into an object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes is called the object representation of the value. ..."

exactly

Exactly where? I do not read "cast" in there. Do you? (I've restored
the Standard's text, above.)
Use of a union with a [preferably 'unsigned'] 'char' (signed
considerations discussed elsethread) array which exactly overlaps some
other member appears to accomplish precisely the same thing
(inspection). The original post referred to a strategy offered in a C
FAQ, if I recall correctly.

Because in appendix J, J.1 unspecific behavior it lists:

- The value of a union member other than the last one stored into

So the standard clearly says that pointers to unsigned char are ok

_Where_? Are you talking about 6.5p7's inclusion of "...an lvalue
expression that has...a character type"? If so, what is the type of
'U.ch[0]'[6.3.2.1p3]? Is that expression an lvalue?
and
that for unions the implementation may decide to throw you some other
values in the face. And this is even "unspecific behavior" and not
"implementation defined", so an implementation is not even obliged to
document this or to be consistent with it.

Are the items in that appendix not "informative" items, to be drawn as
"portability issue" conclusions from the clauses they reference? If so,
where do you see a problem, and where do you see anything that makes
casting any better?

The 'ch' member exactly overlaps the 'i' member, so that excludes
6.2.6.1p6's "...that correspond to any padding bytes..." and excludes
p7. p6's "The value of a structure or union object is never a trap
representation..." remains.

I don't think the informative appendix item is supposed to be taken as
meaning, "Discard what you've read thus far in favour of this brief,
definitive statement."

So what's the difference for casting?:

int i = 1;
typedef unsigned char i_obj_repr[sizeof i];
i_obj_repr * ch = (i_obj_repr *) &i;
if (0[*ch] == 1)
/* ... */

in both cases (casting and union), we are saying "There is an array of
character type with 'sizeof (int)' elements at the same address as 'i'
(or member 'i')."
 
T

Tim Rentsch

Jens said:
One way to test for endianess is to use a union:
Is there any particular reason you want to use a union for such a
purpose? Casting any data pointer to unsigned char is the way mandated
by the standard to inspect individual bytes of an object.

Where is this mandated? 6.2.6.1p4 includes:
exactly

Use of a union with a [preferably 'unsigned'] 'char' (signed
considerations discussed elsethread) array which exactly overlaps some
other member appears to accomplish precisely the same thing
(inspection). The original post referred to a strategy offered in a C
FAQ, if I recall correctly.

Because in appendix J, J.1 unspecific behavior it lists:

- The value of a union member other than the last one stored into

So the standard clearly says that pointers to unsigned char are ok and
that for unions the implementation may decide to throw you some other
values in the face. And this is even "unspecific behavior" and not
"implementation defined", so an implementation is not even obliged to
document this or to be consistent with it.

Apparently you have a misunderstanding of the nature of the two
kinds of statements in the Standard.

All statements made in Annex J are 'informative', which means
they do not define the language but just are reflective of
other statements (called 'normative') that officially state
the actual requirements. The statements in Annex J are given
as useful summaries, but they are approximate, not exact,
statements of actual requirements.

The particular entry in this subparagraph of J.1 gives a
reference to 6.2.6.1. The relevant text for this case is
in 6.2.6.1p7, which says:

When a value is stored in a member of an object of union
type, the bytes of the object representation that do not
correspond to that member but do correspond to other members
take unspecified values.

It is only the bytes of other members _that do not correspond
to the member being stored_ that take on unspecified values.
When it happens, as it does in the upthread example, that all
member objects in the union overlap exactly, other members do
_not_ taken on unspecified values but are exactly determined by
the byte values actually stored and the (implementation-defined)
representations of the types in question.

Unions are guaranteed to work in this way for this kind of
access. As long as the byte being accessed corresponds to
a byte of the member object last stored into, its contents
must be exactly the same as the byte of the object representation
that was stored.
 
R

Roberto Waltman

James Waldby said:
So, now we can say we've heard your claim of having heard of a platform
where there was built-in support for floating point math, but no hardware
support for large integer types. ... Did you perhaps happen to hear the
name of said platform?

From foggy memory and without any fact checking: Burroughs 5???
"mainframes"

Integers were stored as the unnormalized mantissa of a floating point
number, and the same opcodes would work with integer and floating
point values.
I believe this was by design, not "a clumsy work-around"

Form more info, comp.arch and alt.folklore.computers would be the
right places to ask.
 
J

James Kuyper

From foggy memory and without any fact checking: Burroughs 5???
"mainframes"

Integers were stored as the unnormalized mantissa of a floating point

The key point, in this context: would the bits making up the mantissa
correspond precisely to either the first or last N bytes of the floating
point number, for some appropriate value of N? If not, it would be an
example of bits not being stored in the locations that would normally be
expected.
 
J

James Waldby

The key point, in this context: would the bits making up the mantissa
correspond precisely to either the first or last N bytes of the floating
point number, for some appropriate value of N? If not, it would be an
example of bits not being stored in the locations that would normally be
expected.

Seems possible. I'm not familiar with B5000 architecture, but
<http://www.smecc.org/The Architecture of the Burroughs B-5000.htm>
says "Arithmetic Instructions. The B6000 has few of these ... hence
only one ADD instruction exists. The B5000 had two ADD instructions, one
each for single and double precision, since ...", and in footnote 6, "the
only difference between a 'real' and an 'integer' is that an integer has an
empty exponent part. However, the 48-bit word still leaves 39-bit integer
precision. Integer subfields of words are extracted using the mask-and-
steering logic to form an integer operand in the A register ..."

As Waltman notes, perhaps "comp.arch and alt.folklore.computers would be
the right places to ask".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

C doubt- union 5
Syntax for union parameter 368
UNION global variabl initialize 10
Union and strict aliasing 4
Union of structs with duplicate var names 4
Union In C 4
Portability issues (union, bitfields) 7
union 16

Members online

No members online now.

Forum statistics

Threads
474,091
Messages
2,570,604
Members
47,223
Latest member
smithjens316

Latest Threads

Top