OVH Cloud OVH Cloud

savoir l'endianess

7 réponses
Avatar
Saïd
Bonjour,

Cest plus une question de gcc, mais bon. Quelle *la* methode standard pour
savoir l'endianess de la machine sur laquelle est compile un programme?
(pour effectuer deux actions differentes suivant le l'endian)

--
Saïd.
C programmers never die - they're just cast into void.

7 réponses

Avatar
Eric Lévénez
Le 25/06/05 20:09, dans , « Saïd »
a écrit :

Cest plus une question de gcc, mais bon. Quelle *la* methode standard pour
savoir l'endianess de la machine sur laquelle est compile un programme?
(pour effectuer deux actions differentes suivant le l'endian)


Il n'y a pas de méthode standard (portable) pour savoir cela. Il y a
différentes méthodes.

Soit on utilise un define qui permet d'avoir un code optimisé (DARWIN, X11,
INET... tous ont leurs defines particulier), par exemple :

#include <libc.h>

int main(void)
{
#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
printf("littlen");
#elif __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN
printf("bign");
#else
printf("othern");
#endif
return 0;
}



Soit on utilise une fonction qui retourne cette information. J'ai trouvé
cela :

<http://developer.apple.com/documentation/CoreFoundation/Reference/CFByteOrd
erUtils/Reference/chapter_1.2_section_2.html#//apple_ref/doc/uid/20001449-Do
ntLinkChapterID_2-BAJEJFGJ>



Soit on utilise des fonctions qui gèrent cela en interne comme les fonctions
réseaux :

man byteorder



Soit on fait le test soi-même (avec un union d'un entier et d'un tableau de
char : on assigne l'entier et on lit le premier char).



La dernière méthode est de ne pas utiliser des entiers (> 16 bits) dans les
entrées/sorties. Pour cela on lit octet par octet et on fait des décalages
et des additions comme : (a0 << 24) | (a1 << 16) | (a2 << 8) | a3. Avec
cette méthode on est portable et on ne dépend d'aucune particularité car on
défini soi-même l'ordre des octets (pas forcément big ou little), mais par
contre c'est plus lent qu'une compilation par define.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
ftestuz
Saïd wrote:

Bonjour,

Cest plus une question de gcc, mais bon. Quelle *la* methode standard pour
savoir l'endianess de la machine sur laquelle est compile un programme?
(pour effectuer deux actions differentes suivant le l'endian)


Tu as CFByteOrderGetCurrent() dans CoreFoundation et NSHostByteOrder()
dans Foundation.
Il y a aussi toute une série de fonction (aussi bien en Carbon qu'en
Cocoa) pour transformer des données directement dans l'endianess de la
machine.

<http://developer.apple.com/documentation/CoreFoundation/Reference/CFByt
eOrderUtils/index.html>
ou
<http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Obj
C_classic/Functions/FoundationFunctions.html#//apple_ref/doc/uid/2000005
5> sous Byte Ordering

Après je ne sais pas s'il existe des fonctions plus "bas niveau".

--
Frédéric Testuz

Avatar
ftestuz
Saïd wrote:

Bonjour,

Cest plus une question de gcc, mais bon. Quelle *la* methode standard pour
savoir l'endianess de la machine sur laquelle est compile un programme?
(pour effectuer deux actions differentes suivant le l'endian)


Et si jamais, il y a le chapitre 3 dans
<http://developer.apple.com/documentation/MacOSX/Conceptual/universal_bi
nary/universal_binary.pdf>
Ce chapitre est entièrement sur la question de l'ordre des octets.

--
Frédéric Testuz

Avatar
Schmurtz
Eric Lévénez wrote:

Le 25/06/05 20:09, dans , « Saïd »
a écrit :

Il n'y a pas de méthode standard (portable) pour savoir cela. Il y a
différentes méthodes.

Soit on utilise un define qui permet d'avoir un code optimisé (DARWIN, X11,
INET... tous ont leurs defines particulier), par exemple :

#include <libc.h>

int main(void)
{
#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
printf("littlen");
#elif __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN
printf("bign");
#else
printf("othern");


Ça existe vraiment ? ou c'est juste dans le cas on ne sait pas ?

#endif
return 0;
}


Sinon, je connaissais les macro BYTE_ORDER, LITTLE_ENDIAN et BIG_ENDIAN
utiliser par les fichiers d'include du système.

--
Schmurtz

Avatar
Saïd
Eric Lévénez :
La dernière méthode est de ne pas utiliser des entiers (> 16 bits) dans les
entrées/sorties. Pour cela on lit octet par octet et on fait des décalages
et des additions comme : (a0 << 24) | (a1 << 16) | (a2 << 8) | a3.


J'ai fait comme ca, merci.

--
Saïd.
C programmers never die - they're just cast into void.

Avatar
Eric Lévénez
Le 25/06/05 23:29, dans <42bdccab$0$6385$,
« Schmurtz » a écrit :

Eric Lévénez wrote:

Le 25/06/05 20:09, dans , « Saïd »
a écrit :

Il n'y a pas de méthode standard (portable) pour savoir cela. Il y a
différentes méthodes.

Soit on utilise un define qui permet d'avoir un code optimisé (DARWIN, X11,
INET... tous ont leurs defines particulier), par exemple :

#include <libc.h>

int main(void)
{
#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
printf("littlen");
#elif __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN
printf("bign");
#else
printf("othern");


Ça existe vraiment ? ou c'est juste dans le cas on ne sait pas ?


Cela a existé sur des LSI/11 et PDP/11. Maintenant je ne suis pas sûr que
les processeurs courants aient ce genre d'arrangement de multiplets (pas
forcément octets en plus...). En pratique on met un "#error" dans le "#else"
car le portage n'est pas forcément simple.

#endif
return 0;
}


Sinon, je connaissais les macro BYTE_ORDER, LITTLE_ENDIAN et BIG_ENDIAN
utiliser par les fichiers d'include du système.


Apple semble conseiller dans son "Universal Binary Programming Guidelines"
(page 41) :

#ifdef __BIG_ENDIAN__
#else
#endif

Ce qui n'est pas terrible du tout comme principe vu que si la constante
n'est pas définie, on ne sait pas si c'est parce que l'on est en little ou
si c'est un oubli d'un include et donc d'une définition. Mais bon il semble
que ce define soit en dur dans la version actuelle de gcc (donc cela
marchera du Mac OS X, mais le code ne sera pas forcément portable ailleurs):

$ gcc -E -dM - < /dev/null | grep ENDIAN
#define __BIG_ENDIAN__ 1
#define _BIG_ENDIAN 1

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Eric Lévénez
Le 26/06/05 11:54, dans , « Erwan
David » a écrit :

Il ya des processeurs où les donées 64 bits sont stockées dans 2 mots
de 32 bits. Les octest en little endian dans les mots, et les mots en
big endian...

Si mes souvenirs sont bions on toiuve ça chez Hitachi.


Dans les includes Mach il y a 2 defines pour cela (indépendant de
l'endianess) :

#define _QUAD_HIGHWORD 0 ou 1
#define _QUAD_LOWWORD 0 ou 1

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.