This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]