Big and Little Endian

bridged with qnx.development_tools
Post Reply
JS

Big and Little Endian

Post by JS » Mon Nov 22, 2004 2:21 pm

Hi, I would like to port my application from AIX (Big Endian) to QNX on
Intel (Little Endian). Can anyone tell me what is the best way of doing it?
Can I just set some options in the compiler (preferably) or should I have a
lot of #ifdef in my code (which means a lot of editing to do)? My
application is written in ANSI C and I use a lot of bitwise manipulation.
Thanks.

David Gibbs

Re: Big and Little Endian

Post by David Gibbs » Mon Nov 22, 2004 8:32 pm

JS <jsukamtoh@infolink.co.id> wrote:
Hi, I would like to port my application from AIX (Big Endian) to QNX on
Intel (Little Endian). Can anyone tell me what is the best way of doing it?
Can I just set some options in the compiler (preferably) or should I have a
lot of #ifdef in my code (which means a lot of editing to do)? My
application is written in ANSI C and I use a lot of bitwise manipulation.
Depends on what your code is doing.

Some of the code may require no changes at all. If the data is 100%
interpreted LE, both on generation and processing, you may be able
to completely ignore the endianness of the data in doing your bit
operations. It depends on how much of the knowledge of the bit-ordering
is actually in the data structures.

What do I mean by that?

Well if you do something like:

union {
char bytes[4];
long word;
}

As the way to break word down into 4 bytes, then you're going to have
trouble.

But if you use things like shifting & masking to get a particular byte
out of the word, you'll be ok.

If you need to handle data that was previously generated, or will be
generated in BE, under an LE system -- or vice versa, to generate
output, then you will probably want to use the ENDIAN*() macros documented
in the library reference for conversion.

-David
--
David Gibbs
QNX Training Services
dagibbs@qnx.com

JS

Re: Big and Little Endian

Post by JS » Tue Nov 23, 2004 2:15 am

Thanks.

I have a bit stream being sent as IPC via socket. In order to interpret the
bit, I have casted the stream into a structure called BITMAP_STRUCT, and I
can use ptr->bit5 to get the value. In LE, looks like I have to reversed the
order of the bit in each 8 bit chunk in this structure. Is that all I have
to do in this case?

typedef struct bitmap_struct
{
unsigned short bit1:1;
unsigned short bit2:1;
unsigned short bit3:2;
unsigned short bit4:3;
unsigned short bit5:1;
unsigned short bit6:1;
unsigned short bit7:3;
unsigned short bit8:4;
unsigned short bit9:1;
... up to 128 bits
} BITMAP_STRUCT;



"David Gibbs" <dagibbs@qnx.com> wrote in message
news:cnticp$gva$2@inn.qnx.com...
JS <jsukamtoh@infolink.co.id> wrote:
Hi, I would like to port my application from AIX (Big Endian) to QNX on
Intel (Little Endian). Can anyone tell me what is the best way of doing
it?
Can I just set some options in the compiler (preferably) or should I
have a
lot of #ifdef in my code (which means a lot of editing to do)? My
application is written in ANSI C and I use a lot of bitwise
manipulation.

Depends on what your code is doing.

Some of the code may require no changes at all. If the data is 100%
interpreted LE, both on generation and processing, you may be able
to completely ignore the endianness of the data in doing your bit
operations. It depends on how much of the knowledge of the bit-ordering
is actually in the data structures.

What do I mean by that?

Well if you do something like:

union {
char bytes[4];
long word;
}

As the way to break word down into 4 bytes, then you're going to have
trouble.

But if you use things like shifting & masking to get a particular byte
out of the word, you'll be ok.

If you need to handle data that was previously generated, or will be
generated in BE, under an LE system -- or vice versa, to generate
output, then you will probably want to use the ENDIAN*() macros documented
in the library reference for conversion.

-David
--
David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs

Re: Big and Little Endian

Post by David Gibbs » Tue Nov 23, 2004 3:50 pm

JS <jsukamtoh@infolink.co.id> wrote:
Thanks.

I have a bit stream being sent as IPC via socket. In order to interpret the
bit, I have casted the stream into a structure called BITMAP_STRUCT, and I
can use ptr->bit5 to get the value. In LE, looks like I have to reversed the
order of the bit in each 8 bit chunk in this structure. Is that all I have
to do in this case?
Ok, LE vs BE does NOT change the order of bits within a byte. It changes
the order of bytes within a larger data type (16-bit int, 32-bit int,
64-bit int, etc.).
typedef struct bitmap_struct
{
unsigned short bit1:1;
unsigned short bit2:1;
unsigned short bit3:2;
unsigned short bit4:3;
unsigned short bit5:1;
unsigned short bit6:1;
unsigned short bit7:3;
unsigned short bit8:4;
unsigned short bit9:1;
... up to 128 bits
} BITMAP_STRUCT;
Yuck.

So, I went to my K&R (Ansi C) to look up how bitfields worked, and found:

"Almost everything about fields is implementation-dependent. Whether a
field may overlap a word boundary is implementation-defined. ... Fields
are defined left to right on some machines and right to left on others.
.... programs that depend on such things are not portable."

I went to the C99 specifications, and yup, that hasn't changed. Bitfields
are completely non-portable.

This is not (only) an LE vs BE issue.

I see two choices -- spend some time "discovering" through experimentation
how QNX's implementation lays out bitfields and then create a new bitmap
structure to be able to find the bits you need, or write portable code
that uses masks & shifts to get the bits you need. (To write portable
code, you may wish to consider the hton*() and ntoh*() functions rather
than the ENDIAN*() macros I originally mentioned.)

-David
--
David Gibbs
QNX Training Services
dagibbs@qnx.com

Post Reply

Return to “qnx.development_tools”