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


Groups > comp.lang.c > #6224

Re: Union test for endianess

From Shao Miller <sha0.miller@gmail.com>
Newsgroups comp.lang.c
Subject Re: Union test for endianess
Date 2011-06-17 03:01 -0500
Organization A noiseless patient Spider
Message-ID <iteu3o$8ll$1@dont-email.me> (permalink)
References <f19541de-213c-4744-b712-92f20a3ad294@d26g2000prn.googlegroups.com> <iteme0$3va$1@dont-email.me> <18896aaa-106d-4a43-95bb-a08e13676be2@x38g2000pri.googlegroups.com>

Show all headers | View raw


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

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

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

csiph-web