This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Endian swapping with C code
- From: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- To: Falk Hueffner <hueffner at informatik dot uni-tuebingen dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 23 Jul 2004 17:15:40 +0200 (CEST)
- Subject: Re: Endian swapping with C code
--- Falk Hueffner wrote:
> Etienne Lorrain writes:
> > Then "simply" add a variable attribute:
> > int ethernet_integer __attribute__((bigendian));
> > int intel_integer __attribute__((littleendian));
> > const short int intel_const __attribute__((littleendian)) = 0xFF;
> >
> > It opens optimisation opportunities, warnings if passing a pointer
> > of the wrong endianness, does not clash with integer promotion on
> > function parameters...
>
> Firstly, this would add huge amount of complexity to gcc and be pretty
> error prone.
I do agree, it is complex to implement and debug.
> Secondly, if you remotely care about performance, you
> want endian conversion to happen at exactly one clearly defined place,
> for which a built-in function will do just fine.
That would be very nice, when you receive a buffer containning a
message from another processor in the other endianness, to call
a function which convert all the 32 bits numbers and all the 16
bits numbers to the local endianness.
The usual problem then is to know _where_ are the 16 bits numbers
and the 32 bits numbers in your message buffer.
Most of the time, you will have such a message:
union {
struct {
struct header_t {
enum { mess_type1, mess_type2 } message_discriminant;
...
} header;
unsigned a_32_bit_number;
....
} message_type_1;
struct {
struct header_t header;
unsigned short first_16_bit_number;
unsigned short second_16_bit_number;
....
} message_type_2;
} buffer;
If you call "convert_32bit_endian(&buffer.message_type_1.a_32_bit_number)"
when you received in fact a "buffer.message_type_2" you have just inverted
first_16_bit_number and second_16_bit_number.
In short the function you want cannot be written in this case (with 50
types of messages), and note that at entry of your conversion function
you have to treat an enum in the other endianness, probably by a switch.
The faster way to compare a big endian value to a little endian constant
is to compare the big endian value to the little endian constant converted
at compile time, i.e. in this case:
enum { mess_type1 = big_endian(1), mess_type2 = = big_endian(2) ... }
Note that if you want to byte-swap the complete content of an hard-disk
sector per sector then you need a fast function, as you said.
Etienne.
Vous manquez d?espace pour stocker vos mails ?
Yahoo! Mail vous offre GRATUITEMENT 100 Mo !
Créez votre Yahoo! Mail sur http://fr.benefits.yahoo.com/
Le nouveau Yahoo! Messenger est arrivé ! Découvrez toutes les nouveautés pour dialoguer instantanément avec vos amis. A télécharger gratuitement sur http://fr.messenger.yahoo.com