Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #6215 > unrolled thread

Union test for endianess

Started byBhasker Penta <bskdsp@gmail.com>
First post2011-06-16 20:16 -0700
Last post2011-06-20 12:22 -0700
Articles 20 on this page of 50 — 19 participants

Back to article view | Back to comp.lang.c


Contents

  Union test for endianess Bhasker Penta <bskdsp@gmail.com> - 2011-06-16 20:16 -0700
    Re: Union test for endianess Ian Collins <ian-news@hotmail.com> - 2011-06-17 15:36 +1200
      Re: Union test for endianess Willem <willem@toad.stack.nl> - 2011-06-17 14:13 +0000
        Re: Union test for endianess Joe Wright <joewwright@comcast.net> - 2011-06-17 14:00 -0400
          Re: Union test for endianess Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-06-19 19:25 +0000
    Re: Union test for endianess China Blue Angels <chine.bleu@yahoo.com> - 2011-06-16 20:54 -0700
      Re: Union test for endianess Willem <willem@toad.stack.nl> - 2011-06-17 14:14 +0000
        Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 10:28 -0400
          Re: Union test for endianess Keith Thompson <kst-u@mib.org> - 2011-06-17 10:54 -0700
        Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-17 10:35 -0500
        Re: Union test for endianess "J. J. Farrell" <jjf@bcs.org.uk> - 2011-06-18 01:50 +0100
    Re: Union test for endianess China Blue Angels <chine.bleu@yahoo.com> - 2011-06-16 21:00 -0700
      Re: Union test for endianess Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-06-17 12:09 +0100
    Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-17 00:50 -0500
      Re: Union test for endianess Bhasker Penta <bskdsp@gmail.com> - 2011-06-16 23:17 -0700
        Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-17 03:01 -0500
          Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-17 13:33 -0500
            Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-18 09:18 -0400
            Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-19 17:22 -0500
            Re: Union test for endianess Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-19 16:24 -0700
          Re: Union test for endianess Bhasker Penta <bskdsp@gmail.com> - 2011-06-18 01:08 -0700
          Re: Union test for endianess Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-19 15:52 -0700
    Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 09:32 -0400
      Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 09:52 -0400
        Re: Union test for endianess Bhasker Penta <bskdsp@gmail.com> - 2011-06-17 07:13 -0700
          Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 10:31 -0400
      Re: Union test for endianess "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-06-17 15:57 -0700
        Re: Union test for endianess Keith Thompson <kst-u@mib.org> - 2011-06-17 16:42 -0700
          Re: Union test for endianess James Waldby <not@valid.invalid> - 2011-06-18 02:53 +0000
            Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 23:59 -0400
              Re: Union test for endianess James Waldby <not@valid.invalid> - 2011-06-18 14:45 +0000
                Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-18 11:08 -0400
                Re: Union test for endianess cri@tiac.net (Richard Harter) - 2011-06-18 19:47 +0000
                  Re: Union test for endianess James Waldby <not@valid.invalid> - 2011-06-18 23:15 +0000
                    Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-18 22:42 -0400
                Re: Union test for endianess Jens <jens.gustedt@gmail.com> - 2011-06-19 07:41 -0700
                Re: Union test for endianess Roberto Waltman <usenet@rwaltman.com> - 2011-06-22 11:25 -0400
                  Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-22 11:40 -0400
                    Re: Union test for endianess James Waldby <not@valid.invalid> - 2011-06-22 21:42 +0000
        Re: Union test for endianess James Kuyper <jameskuyper@verizon.net> - 2011-06-17 21:18 -0400
    Re: Union test for endianess falk@rahul.net (Edward A. Falk) - 2011-06-17 20:50 +0000
    Re: Union test for endianess "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-06-18 10:42 -0400
      Re: Union test for endianess Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-06-18 22:55 +0100
        Re: Union test for endianess "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-06-19 21:14 -0400
    Re: Union test for endianess Jens <jens.gustedt@gmail.com> - 2011-06-19 07:46 -0700
      Re: Union test for endianess Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-19 16:14 -0700
      Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-19 20:24 -0500
        Re: Union test for endianess Jens <jens.gustedt@gmail.com> - 2011-06-20 00:31 -0700
          Re: Union test for endianess Shao Miller <sha0.miller@gmail.com> - 2011-06-20 04:33 -0500
          Re: Union test for endianess Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-20 12:22 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#6339

FromBhasker Penta <bskdsp@gmail.com>
Date2011-06-18 01:08 -0700
Message-ID<4777ada9-c9eb-4274-ba1a-6ab6a6a77e87@r27g2000prr.googlegroups.com>
In reply to#6224
On Jun 17, 1:01 pm, Shao Miller <sha0.mil...@gmail.com> wrote:
> On 6/17/2011 1:17 AM, Bhasker Penta wrote:
>
>
>
>
>
> > On Jun 17, 10:50 am, Shao Miller<sha0.mil...@gmail.com>  wrote:
> >> On 6/16/2011 10:16 PM, Bhasker Penta wrote:
>
> >>> One way to test for endianess is to use a union:
>
> >>> void endianTest()
> >>> {
> >>>       union     // sizeof(int) == 4
> >>>       {
> >>>           int i;
> >>>           char ch[4];
> >>>       } U;
>
> >>>       U.i=0x12345678; // writing to int member
> >>>       if ( U.ch[0]==0x78 )   // reading from char member
> >>>           puts("\nLittle endian");
> >>>       else
> >>>           puts("\nBig endian");
> >>> }
>
> >> Please note that
>
> >> One possible way to help to ensure that 'sizeof (int) == 4' and that you
> >> have 8-bit bytes is to:
>
> >>     #define TT_ASSERT(message, test) \
> >>       typedef char (message)[(test) ? 1 : -1]
>
> >>     TT_ASSERT(INT_IS_NOT_4_BYTES, sizeof (int) == 4);
> >>     TT_ASSERT(NOT_8_BIT_BYTE, CHAR_BIT == 8);
>
> >>> Writing to one member of a union and reading from another member is
> >>> implementation defined(K&    R).
>
> >> As far as I know, if 'sizeof (int) == 4' as shown, you can certainly
> >> read from each element of the 'U.ch' array.  C doesn't guarantee that
> >> 'sizeof (int) == 4', of course.
>
> >> Combined with the 'TT_ASSERT's above, you could have your union as:
>
> >>     union {
> >>         unsigned int i;
> >>         unsigned char ch[sizeof (unsigned int)];
> >>       } U;
>
> >> (Note that the use of 'unsigned' attempts to avoid any potential sign
> >> bit complications; the 'TT_ASSERT' might be better off matching, too.)
>
> >>> This example is used for testing
> >>> endianess @ c-faq.com. I know that gcc allows this. Is the above
> >>> snippet to test for endianess legal C or C++?
>
> >> If you know that the implementation definitely uses an 8-bit byte, a
> >> 4-byte 'int', and that there are no padding bits and that '0x12345678'
> >> is within the range of values for 'int', then I'd say yes for "legal C". :)
>
> >> If you know that the implementation definitely uses an 8-bit byte, a
> >> 4-byte 'int', and that there are no padding bits and that '0x12345678'
> >> is within the range of values for 'int', then I'd say yes for "legal C". :)
>
> > At least on my machine (Windows 7 64 bit) sizeof(int)==4,
> > sizeof(char)==1 and '0x12345678' is within 'int' limit. But the fact
> > is we are writing to int member and reading from (different) char
> > member. That doesn't go well with union rules.
>
> I believe it's quite all right.  6.5.2.3p3 has:
>
>    "A postfix expression followed by the . operator and an identifier
> designates a member of a structure or union object. The value is that of
> the named member, and is an lvalue if the first expression is an lvalue.
> If the first expression has qualified type, the result has the
> so-qualified version of the type of the designated member."
>
> Since you are using your 'ch' array, its element type is a character
> type, and there are no trap representations for character types.  The
> last-stored value for the union has an object representation[6.2.6.1p4]
> and that representation is then used for 'ch'.
>
> Which union rules are you worried about, in particular?
>
> > If it is legal in C
> > language to reinterpret the content of any object as a char array (or
> > char pointer), then I believe above snippet is technically correct C
> > code(I may be wrong).
>
> "char array": Yes.  "char pointer": I think you mean if it's accessed
> via a pointer to a character type.  Yes, that's quite often the case.
>
> One of the guarantees of the character types is that all objects can
> have all of their bits manipulated/inspected via access through a
> character type.  This is useful for copying, for example.  Scalar types
> other than character types might have trap representations, if I recall
> correctly.
>
> Another nice thing about character types is that they have the weakest
> alignment requirement; a pointer to a character type can be cast from
> any other pointer-to-object-type because the alignment is fine[6.3.2.3p7].
>
> > Eg.
> >     int i=0x12345678;    //  sizeof(int) == 4
> >      char *p=(char *)&i;
> >      if(*p==0x78)           // reinterpreting int i through a char
> > pointer
> >          puts("Little Endian");
> >      else
> >          puts("Big Endian");
>
> Absolutely as legitimate as your previous code. :)
>
> (Using 'unsigned' variants are "nicer," in my opinion; no sign bit.)

On Jun 17, 1:01 pm, Shao Miller <sha0.mil...@gmail.com> wrote:
> On 6/17/2011 1:17 AM, Bhasker Penta wrote:
>
>
>
>
>
> > On Jun 17, 10:50 am, Shao Miller<sha0.mil...@gmail.com>  wrote:
> >> On 6/16/2011 10:16 PM, Bhasker Penta wrote:
>
> >>> One way to test for endianess is to use a union:
>
> >>> void endianTest()
> >>> {
> >>>       union     // sizeof(int) == 4
> >>>       {
> >>>           int i;
> >>>           char ch[4];
> >>>       } U;
>
> >>>       U.i=0x12345678; // writing to int member
> >>>       if ( U.ch[0]==0x78 )   // reading from char member
> >>>           puts("\nLittle endian");
> >>>       else
> >>>           puts("\nBig endian");
> >>> }
>
> >> Please note that
>
> >> One possible way to help to ensure that 'sizeof (int) == 4' and that you
> >> have 8-bit bytes is to:
>
> >>     #define TT_ASSERT(message, test) \
> >>       typedef char (message)[(test) ? 1 : -1]
>
> >>     TT_ASSERT(INT_IS_NOT_4_BYTES, sizeof (int) == 4);
> >>     TT_ASSERT(NOT_8_BIT_BYTE, CHAR_BIT == 8);
>
> >>> Writing to one member of a union and reading from another member is
> >>> implementation defined(K&    R).
>
> >> As far as I know, if 'sizeof (int) == 4' as shown, you can certainly
> >> read from each element of the 'U.ch' array.  C doesn't guarantee that
> >> 'sizeof (int) == 4', of course.
>
> >> Combined with the 'TT_ASSERT's above, you could have your union as:
>
> >>     union {
> >>         unsigned int i;
> >>         unsigned char ch[sizeof (unsigned int)];
> >>       } U;
>
> >> (Note that the use of 'unsigned' attempts to avoid any potential sign
> >> bit complications; the 'TT_ASSERT' might be better off matching, too.)
>
> >>> This example is used for testing
> >>> endianess @ c-faq.com. I know that gcc allows this. Is the above
> >>> snippet to test for endianess legal C or C++?
>
> >> If you know that the implementation definitely uses an 8-bit byte, a
> >> 4-byte 'int', and that there are no padding bits and that '0x12345678'
> >> is within the range of values for 'int', then I'd say yes for "legal C". :)
>
> >> If you know that the implementation definitely uses an 8-bit byte, a
> >> 4-byte 'int', and that there are no padding bits and that '0x12345678'
> >> is within the range of values for 'int', then I'd say yes for "legal C". :)
>
> > At least on my machine (Windows 7 64 bit) sizeof(int)==4,
> > sizeof(char)==1 and '0x12345678' is within 'int' limit. But the fact
> > is we are writing to int member and reading from (different) char
> > member. That doesn't go well with union rules.
>
> I believe it's quite all right.  6.5.2.3p3 has:
>
>    "A postfix expression followed by the . operator and an identifier
> designates a member of a structure or union object. The value is that of
> the named member, and is an lvalue if the first expression is an lvalue.
> If the first expression has qualified type, the result has the
> so-qualified version of the type of the designated member."
>
> Since you are using your 'ch' array, its element type is a character
> type, and there are no trap representations for character types.  The
> last-stored value for the union has an object representation[6.2.6.1p4]
> and that representation is then used for 'ch'.
>
> Which union rules are you worried about, in particular?
>
> > If it is legal in C
> > language to reinterpret the content of any object as a char array (or
> > char pointer), then I believe above snippet is technically correct C
> > code(I may be wrong).
>
> "char array": Yes.  "char pointer": I think you mean if it's accessed
> via a pointer to a character type.  Yes, that's quite often the case.
>
> One of the guarantees of the character types is that all objects can
> have all of their bits manipulated/inspected via access through a
> character type.  This is useful for copying, for example.  Scalar types
> other than character types might have trap representations, if I recall
> correctly.
>
> Another nice thing about character types is that they have the weakest
> alignment requirement; a pointer to a character type can be cast from
> any other pointer-to-object-type because the alignment is fine[6.3.2.3p7].
>
> > Eg.
> >     int i=0x12345678;    //  sizeof(int) == 4
> >      char *p=(char *)&i;
> >      if(*p==0x78)           // reinterpreting int i through a char
> > pointer
> >          puts("Little Endian");
> >      else
> >          puts("Big Endian");
>
> Absolutely as legitimate as your previous code. :)
>
> (Using 'unsigned' variants are "nicer," in my opinion; no sign bit.)

I have done some reading on this matter online.
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
seems to be helpful. From the site:

[ Strictly speaking, reading a member of a union different from the
one written to is undefined in ANSI/ISO C99 except in the special case
of type-punning to a char*. ]

I modified my code:

void endianTest_union()
{
    union     // sizeof(int) == 4
    {
        int i;
        unsigned char ch[4];
    } U;

    U.i = 0x12345678;        // writing to int i

    if(U.ch[0]==0x78 && U.ch[1]==0x56
            && U.ch[2]==0x34 && U.ch[3]==0x12)  // followed by
        puts("Little Endian");                  //reading from
unsigned char: OK

    else if (U.ch[3]==0x78 && U.ch[2]==0x56
             && U.ch[1]==0x34 && U.ch[0]==0x12)
        puts("Big Endian");
    else
        puts("Middle Endian");
}

void endianTest_sans_union()
{
    int n = 0x12345678;     // sizeof(int) == 4
    unsigned char* p = (unsigned char*)&n;   // reinterpreting int
                                             // through unsigned char
ptr: OK
    if(p[0]==0x78 && p[1]==0x56
       && p[2]==0x34 && p[3]==0x12)
        puts("Little Endian");

    else if (p[3]==0x78 && p[2]==0x56
       && p[1]==0x34 && p[0]==0x12)
        puts("Big Endian");

    else
        puts("Middle Endian");
}

void undef_beh()
{
    int n = 0x12345678;     // sizeof(int) == 4
    short int * p = (short int *)&n;   // reinterpreting int
                                       // through short int ptr: not
OK
    printf("\nlower short int: %x\n",p[0]);  // breaks strict aliasing
rule
    printf("higher short int: %x\n",p[1]);   // fortunately this
produces warning (in gcc)
                                          // still prints p[0] ==
0x5678; p[1] == 0x1234
}

void undef_beh_union()
{
    union     // sizeof(int) == 4
    {
        int i;
        short int p[2];
    } U;

    U.i = 0x12345678;        // writing to int i

    printf("\nlower short int: %x\n",U.p[0]);  // followed by
    printf("higher short int: %x\n",U.p[1]);   // reading from short
int member : not OK
                                          // prints U.ch[0] == 0x5678;
U.ch[1] == 0x1234
}                                          // this is implementation
defined (K & R)

PS. Above code @ http://codepad.org/fYbOei62

I have come to the conclusion that code from endianTest_union(),
endianTest_sans_union() is standard complaint while the code from
undef_beh() and  undef_beh_union() is not.

[toc] | [prev] | [next] | [standalone]


#6473

FromTim Rentsch <txr@alumni.caltech.edu>
Date2011-06-19 15:52 -0700
Message-ID<kfn7h8hh1sy.fsf@x-alumni2.alumni.caltech.edu>
In reply to#6224
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Shao Miller <sha0.miller@gmail.com> writes:
>>Which union rules are you worried about, in particular?
>
>   One might worry about not knowing whether or where C actually
>   specifies the value of a certain member. For example, in
>
>       U.i=0x12345678; // writing to int member
>       if ( U.ch[0]==0x78 )   // reading from char member
>
>   or
>
>       int i=0x12345678;    //  sizeof(int) == 4
>       char *ch=(char *)&i;
>
>   , we assume that the value *ch is a >>window<< into the
>   in-memory representation of i. but does the C standard
>   actually requires an implementation to behave this way
>   somewhere? If so, where?

Yes.  The key link is 6.2.5p20, third subparagraph.  Those
who desire further evidence might want to read the footnote
referenced in 6.5.2.3p3 (describing the . and -> operators).

[toc] | [prev] | [next] | [standalone]


#6232

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-17 09:32 -0400
Message-ID<itfl14$g6b$1@dont-email.me>
In reply to#6215
On 06/16/2011 11:16 PM, Bhasker Penta wrote:
> One way to test for endianess is to use a union:
> 
> void endianTest()
> {
>     union     // sizeof(int) == 4
>     {
>         int i;
>         char ch[4];
>     } U;
> 
>     U.i=0x12345678; // writing to int member
>     if ( U.ch[0]==0x78 )   // reading from char member
>         puts("\nLittle endian");
>     else
>         puts("\nBig endian");
> }

There's a total of 24 possible byte orders for 4-byte integers, and a
few of the other 22 orders have in fact been used. The other 22 orders
are generically referred to as "middle-endian", and 5 of them would have
a value of 0x78 in ch[0]. I once found a web page listing the byte
orders that had actually been used, and citing specific machines on
which they had been used - unfortunately, I didn't save it, and have
been unable to locate it again. Big-endian and little-endian were
overwhelmingly the most common orders, but the two orders that were next
most common would set ch[] to {0x34, 0x12, 0x78, 0x56} or {0x56, 0x78,
0x34, 0x12}. One of those two orders (I'm not sure which) was the one
used on the PDP-11 where I did my first C programming. There were
several other orders also in actual use, though far less commonly even
then those two.

> Writing to one member of a union and reading from another member is
> implementation defined(K & R). This example is used for testing
> endianess @ c-faq.com. I know that gcc allows this. Is the above
> snippet to test for endianess legal C or C++?

Neither C nor C++ use the term legal. It contains no syntax errors, it
has no a constraint violations, no diagnostics are required, and the
behavior is not undefined, according to the rules of either language. In
C++ it qualifies as "well-formed code". The closest comparable term in C
is "strictly conforming", but it doesn't qualify for that: it produces
different results on different platforms, which is the whole point of
this particular program, but such platform dependence is prohibited for
strictly conforming programs.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6233

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-17 09:52 -0400
Message-ID<itfm7e$mkl$2@dont-email.me>
In reply to#6232
On 06/17/2011 09:32 AM, James Kuyper wrote:
...
> been unable to locate it again. Big-endian and little-endian were
> overwhelmingly the most common orders, but the two orders that were next
> most common would set ch[] to {0x34, 0x12, 0x78, 0x56} or {0x56, 0x78,
> 0x34, 0x12}. 

Correction: the second one should have been {0x56, 0x78, 0x12, 0x34}.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6235

FromBhasker Penta <bskdsp@gmail.com>
Date2011-06-17 07:13 -0700
Message-ID<49c232dd-29c2-4390-a70c-f07a26933211@17g2000prr.googlegroups.com>
In reply to#6233
On Jun 17, 6:52 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 06/17/2011 09:32 AM, James Kuyper wrote:
> ...
>
> > been unable to locate it again. Big-endian and little-endian were
> > overwhelmingly the most common orders, but the two orders that were next
> > most common would set ch[] to {0x34, 0x12, 0x78, 0x56} or {0x56, 0x78,
> > 0x34, 0x12}.
>
> Correction: the second one should have been {0x56, 0x78, 0x12, 0x34}.
> --
> James Kuyper

Nice info.
About the snippet, according to you, is the code platform dependent
even if one is reading from unsigned char members?

[toc] | [prev] | [next] | [standalone]


#6239

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-17 10:31 -0400
Message-ID<itfog5$6cb$2@dont-email.me>
In reply to#6235
On 06/17/2011 10:13 AM, Bhasker Penta wrote:
> On Jun 17, 6:52�pm, James Kuyper <jameskuy...@verizon.net> wrote:
>> On 06/17/2011 09:32 AM, James Kuyper wrote:
>> ...
>>
>>> been unable to locate it again. Big-endian and little-endian were
>>> overwhelmingly the most common orders, but the two orders that were next
>>> most common would set ch[] to {0x34, 0x12, 0x78, 0x56} or {0x56, 0x78,
>>> 0x34, 0x12}.
>>
>> Correction: the second one should have been {0x56, 0x78, 0x12, 0x34}.
>> --
>> James Kuyper
> 
> Nice info.
> About the snippet, according to you, is the code platform dependent
> even if one is reading from unsigned char members?

Of course - the purpose of the code is to produce platform dependent
behavior: it's supposed to report whether or not the platform is
big-endian or little-endian. While the code, as written, does not
correctly perform that test, the test it does perform is also platform
dependent.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6311

From"christian.bau" <christian.bau@cbau.wanadoo.co.uk>
Date2011-06-17 15:57 -0700
Message-ID<4eb1a4f9-c71d-4c36-a5e6-8e76cfef947b@d1g2000yqm.googlegroups.com>
In reply to#6232
On Jun 17, 2:32 pm, James Kuyper <jameskuy...@verizon.net> wrote:

> Neither C nor C++ use the term legal. It contains no syntax errors, it
> has no a constraint violations, no diagnostics are required, and the
> behavior is not undefined, according to the rules of either language. In
> C++ it qualifies as "well-formed code". The closest comparable term in C
> is "strictly conforming", but it doesn't qualify for that: it produces
> different results on different platforms, which is the whole point of
> this particular program, but such platform dependence is prohibited for
> strictly conforming programs.

Is there actually any guarantee in the C Standard that there is such a
thing as "byte order"? I thought with 32 bit ints stored in 32 bits
worth of bytes there would be 32! (32 factorial) possible bit orders?

[toc] | [prev] | [next] | [standalone]


#6316

FromKeith Thompson <kst-u@mib.org>
Date2011-06-17 16:42 -0700
Message-ID<ln7h8kyqhc.fsf@nuthaus.mib.org>
In reply to#6311
"christian.bau" <christian.bau@cbau.wanadoo.co.uk> writes:
> On Jun 17, 2:32 pm, James Kuyper <jameskuy...@verizon.net> wrote:
>> Neither C nor C++ use the term legal. It contains no syntax errors, it
>> has no a constraint violations, no diagnostics are required, and the
>> behavior is not undefined, according to the rules of either language. In
>> C++ it qualifies as "well-formed code". The closest comparable term in C
>> is "strictly conforming", but it doesn't qualify for that: it produces
>> different results on different platforms, which is the whole point of
>> this particular program, but such platform dependence is prohibited for
>> strictly conforming programs.
>
> Is there actually any guarantee in the C Standard that there is such a
> thing as "byte order"? I thought with 32 bit ints stored in 32 bits
> worth of bytes there would be 32! (32 factorial) possible bit orders?

C99 6.2.6.1 requires a "pure binary notation" for unsigned bit-fields
and objects of type unsigned char, with a footnote:

    A positional representation for integers that uses the binary
    digits 0 and 1, in which the values represented by successive
    bits are additive, begin with 1, and are multiplied by successive
    integral powers of 2,  except perhaps the bit with the highest
    position.

The words "positional" and "successive" imply to me that only two
bit orders are permitted for unsigned char.  (Or perhaps just one;
it's not at all clear that there's even any meaning to the positions
of the bits beyond the values they represent.)

6.2.6.2, discussing the representation of unsigned integer types,
again uses the phrase "pure binary notation".

Each integer type is required to have the same values for its value
bits as the corresponding bits in the corresponding unsigned type.

Though it's not 100% clear what "successive" means.  I supppose
it could just mean traversing the bits in order of the values they
represent, which isn't necessarily the same as either the order of
the bits in the constituent bytes or the physical order (if that's
even meaningful).

I think that either it permits 32 factorial bit orders for a 32-bit
integer, or it forbids PDP-11 middle-endian order (and I seriously
doubt that the latter was intended.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <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"

[toc] | [prev] | [next] | [standalone]


#6329

FromJames Waldby <not@valid.invalid>
Date2011-06-18 02:53 +0000
Message-ID<ith3vr$90o$1@dont-email.me>
In reply to#6316
On Fri, 17 Jun 2011 16:42:39 -0700, Keith Thompson wrote:
> "christian.bau" ... writes:
...
>> Is there actually any guarantee in the C Standard that there is such a
>> thing as "byte order"? I thought with 32 bit ints stored in 32 bits
>> worth of bytes there would be 32! (32 factorial) possible bit orders?
> 
> C99 6.2.6.1 requires a "pure binary notation" for unsigned bit-fields
> and objects of type unsigned char, with a footnote:
[#40 that defines pure binary]
> The words "positional" and "successive" imply to me that only two bit
> orders are permitted for unsigned char.  (Or perhaps just one; it's not
> at all clear that there's even any meaning to the positions of the bits
> beyond the values they represent.)
> 
> 6.2.6.2, discussing the representation of unsigned integer types, again
> uses the phrase "pure binary notation".
> 
> Each integer type is required to have the same values for its value bits
> as the corresponding bits in the corresponding unsigned type.
> 
> Though it's not 100% clear what "successive" means.  I supppose it could
> just mean traversing the bits in order of the values they represent,
> which isn't necessarily the same as either the order of the bits in the
> constituent bytes or the physical order (if that's even meaningful).

On general purpose computers without special sensors, no portable 
program can discover the relative spatial positions of electrons 
that represent data bits, making physical order of bits irrelevant.

The logical succession order of bits in unsigned chars as revealed
by C's <<, >> shift operators cannot differ from arithmetic order, 
because C99 6.5.7 specifies <<, >> in terms of multiplication and
division by powers of 2.  It appears that in the context of C99 C 
there is only one possible bit succession order within unsigned bit 
fields and unsigned chars, which is the 1, 2, 4... order referred to
in footnote 40.

> I think that either it permits 32 factorial bit orders for a 32-bit
> integer, or it forbids PDP-11 middle-endian order (and I seriously doubt
> that the latter was intended.)

Apparently the PDP-11 order is allowed.  When CHAR_BIT is 8, a 
32-bit integer is composed of 4 bytes.  By 6.2.6.1 para. 2, "Except 
for bit-fields, objects are composed of contiguous sequences of one 
or more bytes, the number, order, and encoding of which are either 
explicitly specified or implementation-defined."

-- 
jiw

[toc] | [prev] | [next] | [standalone]


#6332

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-17 23:59 -0400
Message-ID<ith7rm$rjn$1@dont-email.me>
In reply to#6329
On 06/17/2011 10:53 PM, James Waldby wrote:
...
> On general purpose computers without special sensors, no portable 
> program can discover the relative spatial positions of electrons 
> that represent data bits, making physical order of bits irrelevant.

True.

> The logical succession order of bits in unsigned chars as revealed
> by C's <<, >> shift operators cannot differ from arithmetic order, 
> because C99 6.5.7 specifies <<, >> in terms of multiplication and
> division by powers of 2.  It appears that in the context of C99 C 
> there is only one possible bit succession order within unsigned bit 
> fields and unsigned chars, which is the 1, 2, 4... order referred to
> in footnote 40.

Not quite. C allows access to the object representation of an object as
an array of unsigned char. If I set an unsigned long object to store a
value of 1, It's a meaningful question to ask which bit of which byte is
set as a result. I believe that the standard's use of the term
"successive" should not be interpreted as mandating that it be the
lowest order bit of any of those bytes; it could be a bit that has a
value of 8 in the third byte, for instance.

I've heard of a platform where there was built-in support for floating
point math, but no hardware support for large integer types. A clumsy
work-around was created, that implemented a large integer type by using
floating point operations. For such an implementation, bits would almost
certainly not be found in any of the normally expected places in the
underlying array of unsigned char.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6359

FromJames Waldby <not@valid.invalid>
Date2011-06-18 14:45 +0000
Message-ID<itidlj$5su$1@dont-email.me>
In reply to#6332
On Fri, 17 Jun 2011 23:59:50 -0400, James Kuyper wrote:
> On 06/17/2011 10:53 PM, James Waldby wrote: 
...
>> The logical succession order of bits in unsigned chars as revealed by
>> C's <<, >> shift operators cannot differ from arithmetic order, because
>> C99 6.5.7 specifies <<, >> in terms of multiplication and division by
>> powers of 2.  It appears that in the context of C99 C there is only one
>> possible bit succession order within unsigned bit fields and unsigned
>> chars, which is the 1, 2, 4... order referred to in footnote 40.
> 
> Not quite. C allows access to the object representation of an object as
> an array of unsigned char. If I set an unsigned long object to store a
> value of 1, It's a meaningful question to ask which bit of which byte is
> set as a result. I believe that the standard's use of the term
> "successive" should not be interpreted as mandating that it be the
> lowest order bit of any of those bytes; it could be a bit that has a
> value of 8 in the third byte, for instance.

I disagree with the first two words of the your reply.  My paragraph 
to which you respond discusses bit succession order in unsigned bit 
fields and unsigned chars, and does not address bit order in unsigned 
longs.  I agree that when non-integer hardware is used to implement
integer arithmetic, the units bit of an integer might often not be 
the low bit of a byte.

> I've heard of a platform where there was built-in support for floating
> point math, but no hardware support for large integer types. A clumsy
> work-around was created, that implemented a large integer type by using
> floating point operations. For such an implementation, bits would almost
> certainly not be found in any of the normally expected places in the
> underlying array of unsigned char.

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?

-- 
jiw

[toc] | [prev] | [next] | [standalone]


#6362

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-18 11:08 -0400
Message-ID<itif1a$upb$1@dont-email.me>
In reply to#6359
On 06/18/2011 10:45 AM, James Waldby wrote:
> On Fri, 17 Jun 2011 23:59:50 -0400, James Kuyper wrote:
>> On 06/17/2011 10:53 PM, James Waldby wrote: 
> ...
>>> The logical succession order of bits in unsigned chars as revealed by
>>> C's <<, >> shift operators cannot differ from arithmetic order, because
>>> C99 6.5.7 specifies <<, >> in terms of multiplication and division by
>>> powers of 2.  It appears that in the context of C99 C there is only one
>>> possible bit succession order within unsigned bit fields and unsigned
>>> chars, which is the 1, 2, 4... order referred to in footnote 40.
>>
>> Not quite. C allows access to the object representation of an object as
>> an array of unsigned char. If I set an unsigned long object to store a
>> value of 1, It's a meaningful question to ask which bit of which byte is
>> set as a result. I believe that the standard's use of the term
>> "successive" should not be interpreted as mandating that it be the
>> lowest order bit of any of those bytes; it could be a bit that has a
>> value of 8 in the third byte, for instance.
> 
> I disagree with the first two words of the your reply.  My paragraph 
> to which you respond discusses bit succession order in unsigned bit 
> fields and unsigned chars, and does not address bit order in unsigned 
> longs.  I agree that when non-integer hardware is used to implement
> integer arithmetic, the units bit of an integer might often not be 
> the low bit of a byte.
> 
>> I've heard of a platform where there was built-in support for floating
>> point math, but no hardware support for large integer types. A clumsy
>> work-around was created, that implemented a large integer type by using
>> floating point operations. For such an implementation, bits would almost
>> certainly not be found in any of the normally expected places in the
>> underlying array of unsigned char.
> 
> 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?

All that matters to me is the fact that such a implementation could be
made fully conforming, and that's why I remember it. I don't even care
whether such an implementation ever actually existed, so I didn't bother
remembering the name, if indeed I ever knew what the name was.

-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6374

Fromcri@tiac.net (Richard Harter)
Date2011-06-18 19:47 +0000
Message-ID<4dfcffbd.27863166@text.giganews.com>
In reply to#6359
On Sat, 18 Jun 2011 14:45:08 +0000 (UTC), James Waldby
<not@valid.invalid> wrote:

>On Fri, 17 Jun 2011 23:59:50 -0400, James Kuyper wrote:
[snip]

>> I've heard of a platform where there was built-in support for floating
>> point math, but no hardware support for large integer types. A clumsy
>> work-around was created, that implemented a large integer type by using
>> floating point operations. For such an implementation, bits would almost
>> certainly not be found in any of the normally expected places in the
>> underlying array of unsigned char.
>
>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?

The CDC 6600 had 60 bit floating point hardware and no integer support
at all, IIRC.  It also used ones-complement arithmetic.  IIANM there
was a C compiler before it became obsolete.


[toc] | [prev] | [next] | [standalone]


#6397

FromJames Waldby <not@valid.invalid>
Date2011-06-18 23:15 +0000
Message-ID<itjbi5$tn8$1@dont-email.me>
In reply to#6374
On Sat, 18 Jun 2011 19:47:39 +0000, Richard Harter wrote:
> On Sat, 18 Jun 2011 14:45:08 +0000 (UTC), James Waldby wrote:
>>On Fri, 17 Jun 2011 23:59:50 -0400, James Kuyper wrote:
> [snip] 
>>> I've heard of a platform where there was built-in support for floating
>>> point math, but no hardware support for large integer types. A clumsy
>>> work-around was created, that implemented a large integer type by
>>> using floating point operations. For such an implementation, bits
>>> would almost certainly not be found in any of the normally expected
>>> places in the underlying array of unsigned char.
>>
>>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?
> 
> The CDC 6600 had 60 bit floating point hardware and no integer
> support at all, IIRC.  It also used ones-complement arithmetic.

The 6600 has a long add functional unit to do 60-bit integer add 
and subtract, and increment units that can do 18-bit integer add
and subtract, so there is indeed some integer support directly in 
hardware, but not enough to support C.  Instead, integer divide and
multiply are done using floating point divide and multiply units
[as described, eg, in text from CDC 6600 reference manual at
<http://ed-thelen.org/comp-hist/CDC-6600-R-M.html#P3-21>].

As Kuyper suggested, the method is clumsy.  However, the bits of
integer numbers would not end up in unexpected places if integer 
arithmetic is done as described in the reference manual, so the
6600 does not, a priori, support his claim about bits not being
found in normally expected places.  I agree that it is conceivable
that a compliant implementation may exist that supports his claim,
but don't regard the 6600 as likely to provide one.

> IIANM there was a C compiler before it became obsolete.

-- 
jiw

[toc] | [prev] | [next] | [standalone]


#6405

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-18 22:42 -0400
Message-ID<itjnm5$rc3$1@dont-email.me>
In reply to#6397
On 06/18/2011 07:15 PM, James Waldby wrote:
> On Sat, 18 Jun 2011 19:47:39 +0000, Richard Harter wrote:
...
>> The CDC 6600 had 60 bit floating point hardware and no integer
>> support at all, IIRC.  It also used ones-complement arithmetic.
> 
> The 6600 has a long add functional unit to do 60-bit integer add 
> and subtract, and increment units that can do 18-bit integer add
> and subtract, so there is indeed some integer support directly in 
> hardware, but not enough to support C.  Instead, integer divide and
> multiply are done using floating point divide and multiply units
> [as described, eg, in text from CDC 6600 reference manual at
> <http://ed-thelen.org/comp-hist/CDC-6600-R-M.html#P3-21>].
> 
> As Kuyper suggested, the method is clumsy.  However, the bits of
> integer numbers would not end up in unexpected places if integer 
> arithmetic is done as described in the reference manual, so the
> 6600 does not, a priori, support his claim about bits not being
> found in normally expected places.  I agree that it is conceivable
> that a compliant implementation may exist that supports his claim,
> but don't regard the 6600 as likely to provide one.

The example I remember hearing essentially used the mantissa portion of
a 64-bit floating point format to store large integers. The number of
bits in the mantissa was not 32, and obviously could not have been 64,
so that representation didn't put any of the value bits in the locations
that would be expected by anyone unfamiliar with that peculiar format.
If that doesn't describe the CDC-6600, then it's not the one I was told
about.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6446

FromJens <jens.gustedt@gmail.com>
Date2011-06-19 07:41 -0700
Message-ID<60ca5bf4-6fb6-4995-9ab4-5f628d36bad2@w4g2000yqm.googlegroups.com>
In reply to#6359
On 18 Jun., 16:45, James Waldby <n...@valid.invalid> wrote:

> 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?

ix86 for some x in 3..5

I didn't check, but I have a vague memory that egc (was it?), the once
fork of gcc that became mainline then again, had patches to implement
64bit integers in place of doubles on the i586.

Jens

[toc] | [prev] | [next] | [standalone]


#6615

FromRoberto Waltman <usenet@rwaltman.com>
Date2011-06-22 11:25 -0400
Message-ID<1u140713eeqg0tamspubbucq7hc8tanuj0@4ax.com>
In reply to#6359
James Waldby <not@valid.invalid> wrote:
> James Kuyper wrote:
>> I've heard of a platform where there was built-in support for floating
>> point math, but no hardware support for large integer types. A clumsy
>> work-around was created, that implemented a large integer type by using
>> floating point operations. For such an implementation, bits would almost
>> certainly not be found in any of the normally expected places in the
>> underlying array of unsigned char.
>
>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.
--
Roberto Waltman

[ Please reply to the group.
  Return address is invalid ]

[toc] | [prev] | [next] | [standalone]


#6617

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-22 11:40 -0400
Message-ID<itt2ea$du7$1@dont-email.me>
In reply to#6615
On 06/22/2011 11:25 AM, Roberto Waltman wrote:
> James Waldby <not@valid.invalid> wrote:
>> James Kuyper wrote:
>>> I've heard of a platform where there was built-in support for floating
>>> point math, but no hardware support for large integer types. A clumsy
>>> work-around was created, that implemented a large integer type by using
>>> floating point operations. For such an implementation, bits would almost
>>> certainly not be found in any of the normally expected places in the
>>> underlying array of unsigned char.
>>
>> 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

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.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#6670

FromJames Waldby <not@valid.invalid>
Date2011-06-22 21:42 +0000
Message-ID<ittnkj$ib8$2@dont-email.me>
In reply to#6617
On Wed, 22 Jun 2011 11:40:58 -0400, James Kuyper wrote:
> On 06/22/2011 11:25 AM, Roberto Waltman wrote:
>> James Waldby <not@valid.invalid> wrote:
>>> James Kuyper wrote:
>>>> I've heard of a platform where there was built-in support for
>>>> floating point math, but no hardware support for large integer types.
>>>> A clumsy work-around was created, that implemented a large integer
>>>> type by using floating point operations. For such an implementation,
>>>> bits would almost certainly not be found in any of the normally
>>>> expected places in the underlying array of unsigned char.
>>>
>>> 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
> 
> 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%20Architecture%20%20of%20the%20Burroughs%20B-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".

-- 
jiw

[toc] | [prev] | [next] | [standalone]


#6324

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-06-17 21:18 -0400
Message-ID<itguci$8d8$1@dont-email.me>
In reply to#6311
On 06/17/2011 06:57 PM, christian.bau wrote:
> On Jun 17, 2:32�pm, James Kuyper <jameskuy...@verizon.net> wrote:
> 
>> Neither C nor C++ use the term legal. It contains no syntax errors, it
>> has no a constraint violations, no diagnostics are required, and the
>> behavior is not undefined, according to the rules of either language. In
>> C++ it qualifies as "well-formed code". The closest comparable term in C
>> is "strictly conforming", but it doesn't qualify for that: it produces
>> different results on different platforms, which is the whole point of
>> this particular program, but such platform dependence is prohibited for
>> strictly conforming programs.
> 
> Is there actually any guarantee in the C Standard that there is such a
> thing as "byte order"?

No, my comments were only aimed at platforms for which the concept was
meaningful.

> ... I thought with 32 bit ints stored in 32 bits
> worth of bytes there would be 32! (32 factorial) possible bit orders?

That's also true; but it's so esoteric an issue that I thought it better
to raise the byte-order issue, rather than the bit-order one.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web