Exigence légèrement différente: j'ai besoin d'un test comme celui-ci dans un script de configuration de génération de programme pour déterminer si la machine cible à compiler est un bit ou un petit endian, sans exécuter de code . Le script doit être déposé #define HAVE_LITTLE_ENDIAN 1
dans un en- config.h
tête, sinon #define HAVE_LITTLE_ENDIAN 0
.
La machine cible compilée peut être différente de la machine de construction, car nous pouvons être en compilation croisée, ce qui explique également pourquoi le test ne doit pas essayer d'exécuter du code compilé. Il est hors de question d'avoir un petit programme en C avec une printf
déclaration qui crache la réponse.
Une solution possible est la suivante. Nous générons un fichier appelé conftest.c
qui contient ceci:
#define USPELL(C0, C1, C2, C3) \
((unsigned) C0 << 24 | \
(unsigned) C1 << 16 | \
(unsigned) C2 << 8 | (unsigned) C3)
unsigned x[6] = {
0,
USPELL('L', 'I', 'S', 'P'),
USPELL('U', 'N', 'I', 'X'),
USPELL('C', 'O', 'R', 'E'),
USPELL('D', 'W', 'I', 'M'),
0
};
Maintenant, nous compilons ceci pour conftest.o
utiliser:
$ /path/to/cross-compiling/cc conftest.c -c
Ensuite nous courons:
$ strings conftest.o
PSILXINUEROCMIWD
Si la chaîne PSILXINUEROCMIWD
se produit, la cible est little-endian. Si la chaîne LISPUNIXCOREDWIM
se produit, c'est big-endian. Si aucune des deux chaînes ne se produit ou, ce qui est encore plus étonnant, les deux le sont, le test a échoué.
Cette approche fonctionne parce que les constantes "quatre cc" calculées dans le programme ont des valeurs indépendantes de la machine, indiquant les mêmes entiers, quelle que soit leur finalité. Leur représentation de stockage dans le fichier objet suit l’endianité du système cible, ce qui est visible via la vue basée sur les caractères située sous strings
.
Les deux mots de garde zéro garantissent que la chaîne est isolée. Ce n'est pas strictement nécessaire, mais cela garantit que la chaîne recherchée n'est pas incorporée dans une autre chaîne, ce qui signifie qu'elle la strings
restituera sur une ligne seule.
PS: la USPELL
macro ne met pas entre parenthèses les insertions d'arguments, car elles ont été conçues pour cet usage spécifique, et non pour être réutilisées.