Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Determiner architecture Intel

15 réponses
Avatar
Alain BARTHE
Bonjour,

Je dois determiner dans un code si je suis en architecture little ou big
endian, pour swapper ou non les octets de certains champs.

Le meme code doit tourner sous Linux sur architecture Intel 32 ou 64
bits, et sous Solaris sur Sparc

J'avais precedemment utilise :

#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif

Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.

1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)


2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?


Je predererais utiliser des #ifdef que faire un test de l'ordre des bits...

10 réponses

1 2
Avatar
JKB
Le Fri, 22 Apr 2011 10:56:25 +0200,
Alain BARTHE écrivait :
Bonjour,

Je dois determiner dans un code si je suis en architecture little ou big
endian, pour swapper ou non les octets de certains champs.

Le meme code doit tourner sous Linux sur architecture Intel 32 ou 64
bits, et sous Solaris sur Sparc

J'avais precedemment utilise :

#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif

Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.

1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)


2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?


Je predererais utiliser des #ifdef que faire un test de l'ordre des bits...



Juste une question : est-ce que les ntoh[ls] ne sont pas ce que tu
cherches ?

Cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Avatar
Damien Wyart
* Alain BARTHE in fr.comp.lang.c:
Je dois determiner dans un code si je suis en architecture little ou
big endian, pour swapper ou non les octets de certains champs.



La suggestion de JKB pourrait être un piste.

J'avais precedemment utilise :

#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif

Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.

1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)



Il n'y a pas de constante unique à ma connaissance, mais en plus de
__i386, tu peux aussi tester __amd64 ou __x86_64

2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?



autoconf fournit un moyen assez fiable, sinon c'est un problème assez
complexe, comme expliqué dans ce fil de discussion (en Anglais) :
http://gcc.gnu.org/ml/gcc-help/2007-07/msg00342.html

--
DW
Avatar
Alain BARTHE
Le 22/04/2011 13:15, JKB a écrit :
Le Fri, 22 Apr 2011 10:56:25 +0200,
Alain BARTHE écrivait :
Bonjour,

Je dois determiner dans un code si je suis en architecture little ou big
endian, pour swapper ou non les octets de certains champs.

Le meme code doit tourner sous Linux sur architecture Intel 32 ou 64
bits, et sous Solaris sur Sparc

J'avais precedemment utilise :

#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif

Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.

1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)


2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?


Je predererais utiliser des #ifdef que faire un test de l'ordre des bits...



Juste une question : est-ce que les ntoh[ls] ne sont pas ce que tu
cherches ?

Cordialement,

JKB



Ca pourrait etre une solution, mais je voulais passer par de la
compilation conditionnelle.

J'ai reecrit une surcouche de fread et fwrite que j'appelle
endian_read() et endian_write() qui permettent de lire a la maniere
fread() un nombre de champs de taille connue, tout en swappant les
octets si necessaire.

Je pourrais peut-etre utiliser ntoh[ls], mais ce me ferait reecrire mon
interface, ce que je voulais eviter.

J'ai juste besoin de savoir si je suis en little ou big endian.
Avatar
Alain BARTHE
Le 22/04/2011 13:59, Damien Wyart a écrit :
* Alain BARTHE in fr.comp.lang.c:
Je dois determiner dans un code si je suis en architecture little ou
big endian, pour swapper ou non les octets de certains champs.



La suggestion de JKB pourrait être un piste.

J'avais precedemment utilise :



#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif



Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.



1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)



Il n'y a pas de constante unique à ma connaissance, mais en plus de
__i386, tu peux aussi tester __amd64 ou __x86_64



J'ai effectivement trouve entre temps une solution avec :

#if defined(__i386) || defined(__x86_64)
#define HAVE_TO_SWAP
#endif

Il y aussi :
#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)

qui fonctionne, mais uniquement sous Linux (ou GNU).

Sur Solaris, il y a apparemment, suivant architecture :
#define _BIG_ENDIAN 1 // sur sparc
#define _LITTLE_ENDIAN 1 // sur Intel

Je cherchais a savoir quelle etait la solution la plus "propre" et la
plus generale.

Apparemment, ce n'est pas aussi simple.



2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?



autoconf fournit un moyen assez fiable, sinon c'est un problème assez
complexe, comme expliqué dans ce fil de discussion (en Anglais) :
http://gcc.gnu.org/ml/gcc-help/2007-07/msg00342.html



J'avais effectivement regarde comment marchait autoconf.
Si je me rappelle bien, ils ecrivent un entier 16 bits et regardent la
valeur du premier octet. Ca marche, mais il faut du code.

Merci pour ces infos.
Avatar
JKB
Le Fri, 22 Apr 2011 14:40:18 +0200,
Alain BARTHE écrivait :
Le 22/04/2011 13:15, JKB a écrit :
Le Fri, 22 Apr 2011 10:56:25 +0200,
Alain BARTHE écrivait :
Bonjour,

Je dois determiner dans un code si je suis en architecture little ou big
endian, pour swapper ou non les octets de certains champs.

Le meme code doit tourner sous Linux sur architecture Intel 32 ou 64
bits, et sous Solaris sur Sparc

J'avais precedemment utilise :

#ifdef __i386
#define HAVE_TO_SWAP_BYTES
#endif

Je suis maintenant passe sur un PC 64 bits et la constante __i386 ne
semble plus definie.

1) Quelle constante utiliser pour quelle marche dans tous les cas,
pour detecter une architecture INTEL (32 ou 64 bits)


2) Y a t-il un moyen plus propre pour savoir si on se trouve en
little ou big endian ?


Je predererais utiliser des #ifdef que faire un test de l'ordre des bits...



Juste une question : est-ce que les ntoh[ls] ne sont pas ce que tu
cherches ?

Cordialement,

JKB



Ca pourrait etre une solution, mais je voulais passer par de la
compilation conditionnelle.



Certes, mais on trouve de tout et il y a des trucs un peu plus
tordus que petit et grand boutistes.

J'ai reecrit une surcouche de fread et fwrite que j'appelle
endian_read() et endian_write() qui permettent de lire a la maniere
fread() un nombre de champs de taille connue, tout en swappant les
octets si necessaire.

Je pourrais peut-etre utiliser ntoh[ls], mais ce me ferait reecrire mon
interface, ce que je voulais eviter.

J'ai juste besoin de savoir si je suis en little ou big endian.



Je ne sais pas dans quel sens tournent les octets dits du réseau,
mais un truc aussi bête que if (x == ntohl(x)) devrait donner
quelque chose (à moins qu'il ne faille tester la différence).

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Avatar
espie
In article <4db1772f$0$21103$,
Alain BARTHE wrote:
Ca pourrait etre une solution, mais je voulais passer par de la
compilation conditionnelle.


Pourquoi ? c'est source d'erreur.

J'ai reecrit une surcouche de fread et fwrite que j'appelle
endian_read() et endian_write() qui permettent de lire a la maniere
fread() un nombre de champs de taille connue, tout en swappant les
octets si necessaire.



Ben le swap tu le fais avec ntohs et htons, ca te fait reecrire ton
implementation sans changer l'interface.

A priori, ce que tu veux c'est swapper les octes dans un cas d'endianess
et pas dans l'autre ? c'est exactement ce que font ntohs et htons...
Avatar
Alain BARTHE
Le 22/04/2011 18:11, Marc Espie a écrit :
In article<4db1772f$0$21103$,
Alain BARTHE wrote:
Ca pourrait etre une solution, mais je voulais passer par de la
compilation conditionnelle.


Pourquoi ? c'est source d'erreur.

J'ai reecrit une surcouche de fread et fwrite que j'appelle
endian_read() et endian_write() qui permettent de lire a la maniere
fread() un nombre de champs de taille connue, tout en swappant les
octets si necessaire.



Ben le swap tu le fais avec ntohs et htons, ca te fait reecrire ton
implementation sans changer l'interface.

A priori, ce que tu veux c'est swapper les octes dans un cas d'endianess
et pas dans l'autre ? c'est exactement ce que font ntohs et htons...


Oui, je suis d'accord avec vous.
Si je devais le reecrire, c'est certainement ce que je ferais.

J'ai un code de quelques dizaines de lignes qui fonctionne parfaitement,
que j'avais essaye d'optimiser car je dois lire des donnees volumineuses
(gros tableaux de meme type)

Je charge en memoire avec fread() un paquet de size * items, d'un type
donne, et si je dois swapper, je swappe en memoire chacun de mes items.

Ca fonctionne parfaitement, relative vite, et ce depuis des annees.
Je n'avais pas envie d'y retoucher.

Le seul probleme c'est que j'avais un test #ifdef __i386, qui ne
fonctionne plus depuis l'architecture 64 bits.
Il faut maintenant :
#if defined(__i386) || defined (__x86_64)
#define HAVE_TO_SWAP
#endif

Mon probleme etait de determiner le plus proprement et durablement
possible si je suis en little ou big endian.
J'aimerais que mon code continue a fonctionner quand on passera en 128
bits avec une nouvelle macro #ifdef.

Je pense que le test #if defined(__BYTE_ORDER) && (__BYTE_ORDER ==
__LITTLE_ENDIAN) devrait correspondre parfaitement.

Merci encore pour votre aide.
Avatar
espie
In article <4db3de9c$0$6273$,
Alain BARTHE wrote:
Oui, je suis d'accord avec vous.
Si je devais le reecrire, c'est certainement ce que je ferais.

J'ai un code de quelques dizaines de lignes qui fonctionne parfaitement,
que j'avais essaye d'optimiser car je dois lire des donnees volumineuses
(gros tableaux de meme type)

Je charge en memoire avec fread() un paquet de size * items, d'un type
donne, et si je dois swapper, je swappe en memoire chacun de mes items.

Ca fonctionne parfaitement, relative vite, et ce depuis des annees.
Je n'avais pas envie d'y retoucher.

Le seul probleme c'est que j'avais un test #ifdef __i386, qui ne
fonctionne plus depuis l'architecture 64 bits.
Il faut maintenant :
#if defined(__i386) || defined (__x86_64)
#define HAVE_TO_SWAP
#endif

Mon probleme etait de determiner le plus proprement et durablement
possible si je suis en little ou big endian.
J'aimerais que mon code continue a fonctionner quand on passera en 128
bits avec une nouvelle macro #ifdef.

Je pense que le test #if defined(__BYTE_ORDER) && (__BYTE_ORDER ==
__LITTLE_ENDIAN) devrait correspondre parfaitement.



Bof, bof, bof.

L'avantage de htons et de ntohs, c'est qu'elles sont POSIX. Donc relativement
standard (a peu pres le plus general que tu puisses avoir apres C).

L'inconvenient des constructions a la __BYTE_ORDER, c'est que c'est non
standard. Je viens de verifier sur mon POSIX 2008, je ne vois pas l'ombre
d'un endian.h dans les entetes. Et j'ai aussi cherche __BYTE_ORDER, sans
succes.

De ce point de vue, ton probleme est non resolu: __BYTE_ORDER est strictement
moins propre que htons...

Apres, si tu me dis que tu as la flemme de retoucher ce code, c'est une autre
affaire. Tant que tu ne te mens pas a toi-meme cote proprete et portabilite
du resultat...

Bon apres, deja, en passant de __i386 a __BYTE_ORDER, il y a deja un progres,
parce que quid de i386/powerpc/arm/sparc64/longsoon/superH pour ne citer que
quelques archis couramment en usage ces jours-ci ?

Mais aussi, je passe suffisamment de temps a corriger du code soit-disant
portable pas propre parce que les gens font des trucs dans ton genre pour
avoir des reactions epidermiques a ce type de flemme... ;-)
Avatar
Alain BARTHE
Oui, je suis d'accord avec vous.
Si je devais le reecrire, c'est certainement ce que je ferais.

J'ai un code de quelques dizaines de lignes qui fonctionne parfaitement,
que j'avais essaye d'optimiser car je dois lire des donnees volumineuses
(gros tableaux de meme type)

Je charge en memoire avec fread() un paquet de size * items, d'un type
donne, et si je dois swapper, je swappe en memoire chacun de mes items.

Ca fonctionne parfaitement, relative vite, et ce depuis des annees.
Je n'avais pas envie d'y retoucher.

Le seul probleme c'est que j'avais un test #ifdef __i386, qui ne
fonctionne plus depuis l'architecture 64 bits.
Il faut maintenant :
#if defined(__i386) || defined (__x86_64)
#define HAVE_TO_SWAP
#endif

Mon probleme etait de determiner le plus proprement et durablement
possible si je suis en little ou big endian.
J'aimerais que mon code continue a fonctionner quand on passera en 128
bits avec une nouvelle macro #ifdef.

Je pense que le test #if defined(__BYTE_ORDER)&& (__BYTE_ORDER = >> __LITTLE_ENDIAN) devrait correspondre parfaitement.



Bof, bof, bof.

L'avantage de htons et de ntohs, c'est qu'elles sont POSIX. Donc relativement
standard (a peu pres le plus general que tu puisses avoir apres C).



Une dernière question a propos de ntohs et ntohl()

Si j'ai bien compris ntohs() permet de swapper des entiers courts
(16 bits), ntohl() des entiers long (32 bits).

Que se passe t'il si je dois "swapper" des float (32 bits) ou double (64
bits), ou même des entiers 64 bits ?

Je crois me rappeler avoir regardé ces fontions ntoh[sl] à l'époque,
mais je n'avais trouvé les fonctions équivalents pour les 64 bits.

j'avais regardé aussi la librairie XDR, plus complete,
mais je ne l'avais pas choisie non plus.... Je ne sais plus pourquoi.
Avatar
Antoine Leca
Marc Espie écrivit :
Bon apres, deja, en passant de __i386 a __BYTE_ORDER, il y a deja un progres,
parce que quid de i386/powerpc/arm/sparc64/longsoon/superH pour ne citer que
quelques archis couramment en usage ces jours-ci ?



<TAQUIN>
D'après http://www.openbsd.org/cgi-bin/man.cgi?query¾toh64, rubrique
BUGS, il n'y a que "vax, alpha, i386, and some mips architectures," qui
diffèrent du reste du monde. :-)
</TAQUIN>


{Et oui, je sais que ce texte vient en droite ligne de la page
byteorder(3) de 4.2BSD, et qu'à l'époque il importait de pouvoir
facilement lire les dumps binaires à l'écran.}


Antoine
1 2