Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #6215 > unrolled thread
| Started by | Bhasker Penta <bskdsp@gmail.com> |
|---|---|
| First post | 2011-06-16 20:16 -0700 |
| Last post | 2011-06-20 12:22 -0700 |
| Articles | 20 on this page of 50 — 19 participants |
Back to article view | Back to comp.lang.c
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 1 of 3 [1] 2 3 Next page →
| From | Bhasker Penta <bskdsp@gmail.com> |
|---|---|
| Date | 2011-06-16 20:16 -0700 |
| Subject | Union test for endianess |
| Message-ID | <f19541de-213c-4744-b712-92f20a3ad294@d26g2000prn.googlegroups.com> |
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");
}
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++?
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-17 15:36 +1200 |
| Message-ID | <9600etFu2qU3@mid.individual.net> |
| In reply to | #6215 |
On 06/17/11 03:31 PM, Stefan Ram wrote: > Bhasker Penta<bskdsp@gmail.com> writes: >> U.i=0x12345678; // writing to int member >> if ( U.ch[0]==0x78 ) // reading from char member >> Writing to one member of a union and reading from another member is >> implementation defined(K& R). > > »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« > ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ > ISO/IEC 9899:1999 (E), 6.2.6.1#7 > How is that relevant to the question, which assumes sizeof(int) == 4? > One also might cast a pointer to int into a pointer to char[], > but I assume, dereferencing this might also give unspecified > values in the best case or might result in undefined behavior > in the worst case? Do what? How is that relevant to, well anything? > Endianess is an implementation detail of a higher > programming language that the language wants to hide from > you (information hiding), because usually one does not need > to know it. One even can serialize and deserialize in either > a portable or an implementation specific manner without > knowing this. Who ever writes the serialisation code does need to know. If you need to know the endianess, you are probably writing serialisation code! -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2011-06-17 14:13 +0000 |
| Message-ID | <slrnivmo8n.15tq.willem@toad.stack.nl> |
| In reply to | #6217 |
Ian Collins wrote:
) On 06/17/11 03:31 PM, Stefan Ram wrote:
)> Endianess is an implementation detail of a higher
)> programming language that the language wants to hide from
)> you (information hiding), because usually one does not need
)> to know it. One even can serialize and deserialize in either
)> a portable or an implementation specific manner without
)> knowing this.
)
) Who ever writes the serialisation code does need to know. If you need
) to know the endianess, you are probably writing serialisation code!
He just *specifically* stated that who ever writes the serialisation
code *DOES NOT NEED* to know, so your statement does not make sense.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
[toc] | [prev] | [next] | [standalone]
| From | Joe Wright <joewwright@comcast.net> |
|---|---|
| Date | 2011-06-17 14:00 -0400 |
| Message-ID | <f6udncLSe4HcC2bQnZ2dnUVZ_u6dnZ2d@giganews.com> |
| In reply to | #6236 |
On 6/17/2011 10:13, Willem wrote: > Ian Collins wrote: > ) On 06/17/11 03:31 PM, Stefan Ram wrote: > )> Endianess is an implementation detail of a higher > )> programming language that the language wants to hide from > )> you (information hiding), because usually one does not need > )> to know it. One even can serialize and deserialize in either > )> a portable or an implementation specific manner without > )> knowing this. > ) > ) Who ever writes the serialisation code does need to know. If you need > ) to know the endianess, you are probably writing serialisation code! > > He just *specifically* stated that who ever writes the serialisation > code *DOES NOT NEED* to know, so your statement does not make sense. > > > SaSW, Willem I'm not sure what serialisation code is but I don't think endianness needs to be known. I can write hton and ntoh routines that don't care. But if I did want to know for some reason.. int i = 1; int big = *(char*)&i == 0; ..should do the trick most of the time. -- Joe Wright "If you rob Peter to pay Paul you can depend on the support of Paul."
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-06-19 19:25 +0000 |
| Message-ID | <slrnivsj9s.gtj.grahn+nntp@frailea.sa.invalid> |
| In reply to | #6285 |
On Fri, 2011-06-17, Joe Wright wrote: > On 6/17/2011 10:13, Willem wrote: >> Ian Collins wrote: >> ) On 06/17/11 03:31 PM, Stefan Ram wrote: >> )> Endianess is an implementation detail of a higher >> )> programming language that the language wants to hide from >> )> you (information hiding), because usually one does not need >> )> to know it. One even can serialize and deserialize in either >> )> a portable or an implementation specific manner without >> )> knowing this. >> ) >> ) Who ever writes the serialisation code does need to know. If you need >> ) to know the endianess, you are probably writing serialisation code! >> >> He just *specifically* stated that who ever writes the serialisation >> code *DOES NOT NEED* to know, so your statement does not make sense. >> >> >> SaSW, Willem > > I'm not sure what serialisation code is but I don't think endianness needs > to be known. I can write hton and ntoh routines that don't care. Plus, if you're doing serialization into/from sequences of octets, you don't even need POSIX-line htons/htonl. uint32_t n; ... uint8_t msb = n >> 24; is predictable, yet not endianness-aware. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | China Blue Angels <chine.bleu@yahoo.com> |
|---|---|
| Date | 2011-06-16 20:54 -0700 |
| Message-ID | <chine.bleu-19C0F6.20544016062011@news.eternal-september.org> |
| In reply to | #6215 |
In article <union-20110617051812@ram.dialup.fu-berlin.de>,
ram@zedat.fu-berlin.de (Stefan Ram) wrote:
> Bhasker Penta <bskdsp@gmail.com> writes:
> >U.i=0x12345678; // writing to int member
> >if ( U.ch[0]==0x78 ) // reading from char member
> >Writing to one member of a union and reading from another member is
> >implementation defined(K & R).
>
> »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«
> ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
to bytes of i.
union // sizeof(int) == 4
{
int i;
char ch[4];
} U;
--
I remember finding out about you, | I survived XYZZY-Day.
Everyday my mind is all around you,| I'm whoever you want me to be.
Looking out from my lonely room |Annoying Usenet one post at a time.
Day after day. | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2011-06-17 14:14 +0000 |
| Message-ID | <slrnivmoah.15tq.willem@toad.stack.nl> |
| In reply to | #6218 |
China Blue Angels wrote:
) In article <union-20110617051812@ram.dialup.fu-berlin.de>,
) ram@zedat.fu-berlin.de (Stefan Ram) wrote:
)> ?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?
)> ??????????????????
)
) All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
) to bytes of i.
)
) union // sizeof(int) == 4
) {
) int i;
) char ch[4];
) } U;
Or not. It's UNSPECIFIED.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-06-17 10:28 -0400 |
| Message-ID | <itfoav$6cb$1@dont-email.me> |
| In reply to | #6237 |
On 06/17/2011 10:14 AM, Willem wrote:
> China Blue Angels wrote:
> ) In article <union-20110617051812@ram.dialup.fu-berlin.de>,
> ) ram@zedat.fu-berlin.de (Stefan Ram) wrote:
> )> ?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?
> )> ??????????????????
> )
> ) All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
> ) to bytes of i.
> )
> ) union // sizeof(int) == 4
> ) {
> ) int i;
> ) char ch[4];
> ) } U;
>
> Or not. It's UNSPECIFIED.
As far as I can tell, every single byte of the object representation of
U that correspond to U.ch, is also a byte that corresponds to U.i (and
vice versa). There are no relevant bytes that take on unspecified
values. Are you suggesting otherwise? If so, on what grounds?
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-17 10:54 -0700 |
| Message-ID | <lnaadg1gz1.fsf@nuthaus.mib.org> |
| In reply to | #6238 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 06/17/2011 10:14 AM, Willem wrote:
>> China Blue Angels wrote:
>> ) In article <union-20110617051812@ram.dialup.fu-berlin.de>,
>> ) ram@zedat.fu-berlin.de (Stefan Ram) wrote:
>> )> ?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?
>> )> ??????????????????
>> )
>> ) All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
>> ) to bytes of i.
>> )
>> ) union // sizeof(int) == 4
>> ) {
>> ) int i;
>> ) char ch[4];
>> ) } U;
>>
>> Or not. It's UNSPECIFIED.
>
> As far as I can tell, every single byte of the object representation of
> U that correspond to U.ch, is also a byte that corresponds to U.i (and
> vice versa). There are no relevant bytes that take on unspecified
> values. Are you suggesting otherwise? If so, on what grounds?
And since the representations of int and char are implementation-defined
(meaning the implementation must document them), you can tell, given the
implementation's documentation, what values are stored in ch when you
store a value in i (unless there are padding bits).
--
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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-17 10:35 -0500 |
| Message-ID | <itfooq$9gi$1@dont-email.me> |
| In reply to | #6237 |
On 6/17/2011 9:14 AM, Willem wrote:
> China Blue Angels wrote:
> ) In article<union-20110617051812@ram.dialup.fu-berlin.de>,
> ) ram@zedat.fu-berlin.de (Stefan Ram) wrote:
> )> ?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?
> )> ??????????????????
> )
> ) All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
> ) to bytes of i.
> )
> ) union // sizeof(int) == 4
> ) {
> ) int i;
> ) char ch[4];
> ) } U;
>
> Or not. It's UNSPECIFIED.
What is "it?" The behaviour? The values for each element of 'ch'?
Given that 'sizeof (int) == 4', the 'ch' array member exactly overlaps
the 'i' member. I don't follow you.
[toc] | [prev] | [next] | [standalone]
| From | "J. J. Farrell" <jjf@bcs.org.uk> |
|---|---|
| Date | 2011-06-18 01:50 +0100 |
| Message-ID | <itgsp9$391$1@dont-email.me> |
| In reply to | #6237 |
Willem wrote:
> China Blue Angels wrote:
> ) In article <union-20110617051812@ram.dialup.fu-berlin.de>,
> ) ram@zedat.fu-berlin.de (Stefan Ram) wrote:
> )> ?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?
> )> ??????????????????
> )
> ) All the bytes of i correspond to bytes of ch, and all the bytes of ch correspond
> ) to bytes of i.
> )
> ) union // sizeof(int) == 4
> ) {
> ) int i;
> ) char ch[4];
> ) } U;
>
> Or not. It's UNSPECIFIED.
What do you mean? The OP specifies that in this case sizeof(int) is 4.
In that case all the bytes which correspond to member i also correspond
to member ch. What do you believe to be unspecified?
[toc] | [prev] | [next] | [standalone]
| From | China Blue Angels <chine.bleu@yahoo.com> |
|---|---|
| Date | 2011-06-16 21:00 -0700 |
| Message-ID | <chine.bleu-835811.21003916062011@news.eternal-september.org> |
| In reply to | #6215 |
In article <f19541de-213c-4744-b712-92f20a3ad294@d26g2000prn.googlegroups.com>,
Bhasker Penta <bskdsp@gmail.com> 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");
> }
>
> 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++?
You can use casts to avoid variables.
#define X (((union{int i; char ch[4];}){.i=0x12345678}).ch[0])
#define littleEndian (X==0x78)
#define bigEndian (X==0x01)
--
I remember finding out about you, | I survived XYZZY-Day.
Everyday my mind is all around you,| I'm whoever you want me to be.
Looking out from my lonely room |Annoying Usenet one post at a time.
Day after day. | At least I can stay in character.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-06-17 12:09 +0100 |
| Message-ID | <0.0167e5347a17543f93aa.20110617120946BST.87k4ck7lz9.fsf@bsb.me.uk> |
| In reply to | #6219 |
China Blue Angels <chine.bleu@yahoo.com> writes:
> In article <f19541de-213c-4744-b712-92f20a3ad294@d26g2000prn.googlegroups.com>,
> Bhasker Penta <bskdsp@gmail.com> 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");
>> }
<snip>
> You can use casts to avoid variables.
>
> #define X (((union{int i; char ch[4];}){.i=0x12345678}).ch[0])
> #define littleEndian (X==0x78)
> #define bigEndian (X==0x01)
It's probably worth pointing out that this is (a) C99 and (b) has no
casts!
Since all that's needed is a test for two of the possible byte orders,
I'd avoid using a value that might not be a valid int:
#define X (((union{int i; char ch[sizeof(int)];}){.i=1}).ch[0])
The tests then become X and !X (so I'd use some other name).
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-17 00:50 -0500 |
| Message-ID | <iteme0$3va$1@dont-email.me> |
| In reply to | #6215 |
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". :)
[toc] | [prev] | [next] | [standalone]
| From | Bhasker Penta <bskdsp@gmail.com> |
|---|---|
| Date | 2011-06-16 23:17 -0700 |
| Message-ID | <18896aaa-106d-4a43-95bb-a08e13676be2@x38g2000pri.googlegroups.com> |
| In reply to | #6220 |
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. 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).
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");
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-17 03:01 -0500 |
| Message-ID | <iteu3o$8ll$1@dont-email.me> |
| In reply to | #6221 |
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.)
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-17 13:33 -0500 |
| Message-ID | <itg36b$m9c$1@dont-email.me> |
| In reply to | #6224 |
On 6/17/2011 7:57 AM, Stefan Ram wrote:
> 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?
>
6.2.6.1p4 defines "object representation." The 'i' member and the union
itself have an object representation.
6.2.6.1p5 allows for a an lvalue expression ('U.ch[0]') with a character
type (such as 'char') to read the stored value.
6.5p7 confirms that an lvalue expression with a character type can read
the stored value.
>> 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.
>
> Yes, it would be nice to know, where one can find this.
> In the best case, all the steps needed to prove that *ch
> really has the semantics as intended above.
>
Please see above, plus:
6.2.6p3 states that the representation of 'unsigned char' is "pure binary."
6.2.6.2p1 states that 'unsigned char' is not divided into value bits and
padding bits. Since it has values, that leaves only value bits. That
means that there is no bit which cannot be accessed.
The treatment of 'signed char' and implementations where 'char' is akin
to 'signed char' simply has one of the bits being a sign bit[6.2.6.2p6].
Do you have alternative interpretations of these?
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-06-18 09:18 -0400 |
| Message-ID | <iti8in$lje$1@dont-email.me> |
| In reply to | #6281 |
On 06/18/2011 04:47 AM, Stefan Ram wrote: > Shao Miller <sha0.miller@gmail.com> writes: ... >>> U.i=0x12345678; // writing to int member >>> if ( U.ch[0]==0x78 ) // reading from char > > And - while only �informative� - Annex J, J.1 �unspecified > behavior�, p1, states: > > �The following are unspecified: (...) > > -- The value of a union member other than the last one > stored into (6.2.6.1).� > > Above, �i� is the last union member stored into, so the value > of �ch� is unspecified. (Yes, that can be specifed by an > implementation, but we have not yet seen a quotation of such > an implementation specification here.) Footnote 82: "If the member used to access the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation." Note: neither Annex J nor Footnote 82 are normative; what they say can only be true if it can be derived from normative text. Both cross-reference 6.2.6, but it's less than clear to me that either statement is easily derived from anything it says in 6.2.6. I think that the paragraph you quote from J.1p1 is out of date. I think that footnote 82 describes both the way real implementations have always worked, and the committee's latest thinking on the subject. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-19 17:22 -0500 |
| Message-ID | <itlsqg$j1t$1@dont-email.me> |
| In reply to | #6281 |
On 6/18/2011 3:47 AM, Stefan Ram wrote:
> On 6/17/2011 1:33 PM, Shao Miller wrote:
>> On 6/17/2011 7:57 AM, Stefan Ram wrote:
>>> 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?
>>>
>>
>> 6.2.6.1p4 defines "object representation." The 'i' member and the union
>> itself have an object representation.
>>
>> 6.2.6.1p5 allows for a an lvalue expression ('U.ch[0]') with a character
>> type (such as 'char') to read the stored value.
>>
>> 6.5p7 confirms that an lvalue expression with a character type can read
>> the stored value.
>>
>>>> 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.
>>>
>>> Yes, it would be nice to know, where one can find this.
>>> In the best case, all the steps needed to prove that *ch
>>> really has the semantics as intended above.
>>>
>>
>> Please see above, plus:
>>
>> 6.2.6p3 states that the representation of 'unsigned char' is "pure binary."
>>
>> 6.2.6.2p1 states that 'unsigned char' is not divided into value bits and
>> padding bits. Since it has values, that leaves only value bits. That
>> means that there is no bit which cannot be accessed.
>>
>> The treatment of 'signed char' and implementations where 'char' is akin
>> to 'signed char' simply has one of the bits being a sign bit[6.2.6.2p6].
>>
>> Do you have alternative interpretations of these?
>
> What about ISO/IEC 9899:1999 (E) 6.7.2.1 p12?
>
> »Each non-bit-field member of a structure or union
> object is aligned in an implementation-defined manner
> appropriate to its type.«
>
> When this allows i and ch to have different alignments,
> then the following might not behave as expected here.
>
#1: 'sizeof (char) == 1'[6.5.3.4p3].
#2: The size of a complete object type must be an integral multiple of
the alignment requirement, else arrays would not be possible.
#1 && #2 --> #3: The alignment requirement for 'char' is '1'.
#4: The alignment requirement of an array is equal to the alignment
requirement of the element type.
#3 && #4 --> #5: The alignment requirement of the 'U.ch' array is '1'.
#6: The alignment requirement of 'int' is X.
#7: There is no alignment requirement less than '1'.
#2 && #5 && #6 && #7 --> #8: The alignment requirement of 'U' is X.
Are you suggesting that members of a union might not have their
lowest-addressed byte at the beginning of the union? If so, please note
6.5.8p5:
"When two pointers are compared, the result depends on the relative
locations in the address space of the objects pointed to. If two
pointers to object or incomplete types both point to the same object, or
both point one past the last element of the same array object, they
compare equal. ... All pointers to members of the same union object
compare equal. ..."
And 6.5.9p6:
"Two pointers compare equal if and only if both are null pointers,
both are pointers to the same object (including a pointer to an object
and a subobject at its beginning) or function, both are..."
Also note the lack of any mention of such a license for padding before a
member of a union (other than within the units in which bit-fields
reside, which we aren't considering), but the mentions of padding in
6.7.2.1p13:
"... There may be unnamed padding within a structure object, but not
at its beginning."
and in 6.7.2.1p15:
"There may be unnamed padding at the end of a structure or union."
So are you suggesting that 6.7.2.1p12 is not a restriction on the
alignment requirement of a union type (to satisfy each of its member
types), but rather a license to have padding before a particular member?
>>> >>U.i=0x12345678; // writing to int member
>>> >>if ( U.ch[0]==0x78 ) // reading from char
> And - while only »informative« - Annex J, J.1 »unspecified
> behavior«, p1, states:
>
> »The following are unspecified: (...)
>
> -- The value of a union member other than the last one
> stored into (6.2.6.1).«
>
> Above, »i« is the last union member stored into, so the value
> of »ch« is unspecified. (Yes, that can be specifed by an
> implementation, but we have not yet seen a quotation of such
> an implementation specification here.)
>
What are we discussing here, exactly?
The test function itself is attempting to test for one of two
specifications, both of which include a 4-byte 'int' and (presumably) an
8-bit byte: Little-endian, big-endian.
The values we will find in the elements of the 'ch' array are specified,
in my opinion, insofar as they are the object representation of the 'i'
member, because their sizes are the same and so they exactly overlap.
In the case of 'char' being signed, one of the bits is a sign bit.
If we are questioning whether or not we can know the answer to the
testing function from the C Standard: If we can, the testing function is
redundant. If we cannot, the testing function is fairly close to
serving the intended purpose[*1], right?
[*1] It assumes 'sizeof (int) == 4' and assumes only two possibilities,
allowing for false determinations if these criteria are not met.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2011-06-19 16:24 -0700 |
| Message-ID | <kfntyblflq0.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #6281 |
ram@zedat.fu-berlin.de (Stefan Ram) writes: > Shao Miller <sha0.miller@gmail.com> writes: >>Do you have alternative interpretations of these? > > What about ISO/IEC 9899:1999 (E) 6.7.2.1 p12? > > >>Each non-bit-field member of a structure or union > object is aligned in an implementation-defined manner > appropriate to its type.<< > > When this allows i and ch to have different alignments, > then the following might not behave as expected here. Irrelevant since members in a union object must begin at the same byte address. How the union is aligned might change, but where the members' objects are relative to each other cannot. >>>U.i=0x12345678; // writing to int member >>>if ( U.ch[0]==0x78 ) // reading from char > > And - while only >>informative<< - Annex J, J.1 >>unspecified > behavior<<, p1, states: > > >>The following are unspecified: (...) > > -- The value of a union member other than the last one > stored into (6.2.6.1).<< > > Above, >>i<< is the last union member stored into, so the value > of >>ch<< is unspecified. (Yes, that can be specifed by an > implementation, but we have not yet seen a quotation of such > an implementation specification here.) If you read the referenced section (ie, 6.2.6.1), you will see that this summary is an oversimplification. Only those bytes that don't correspond to the member being stored into take unspecified values -- as must be true because the bytes that _do_ correspond to the member being stored into must take the byte values representing the member's new value, and these bytes coincide with those of other members, because the objects for union members are defined to overlap.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web