Requisito ligeramente diferente: necesito una prueba como esta en un script de configuración de compilación del programa para determinar si la máquina de compilación de destino es bit o little endian, sin ejecutar código . El script debe depositarse #define HAVE_LITTLE_ENDIAN 1
en un config.h
encabezado, o de lo contrario #define HAVE_LITTLE_ENDIAN 0
.
La máquina de compilación de destino puede ser diferente de la máquina de compilación, ya que podemos realizar una compilación cruzada, lo que también explica por qué la prueba no debe intentar ejecutar ningún código compilado. Es imposible tener un pequeño programa en C con una printf
declaración que escupe la respuesta.
Una posible solución es esta. Generamos un archivo llamado conftest.c
que contiene esto:
#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
};
Ahora, compilamos esto para conftest.o
usar:
$ /path/to/cross-compiling/cc conftest.c -c
Luego corremos:
$ strings conftest.o
PSILXINUEROCMIWD
Si se PSILXINUEROCMIWD
produce la cadena , el objetivo es little-endian. Si se LISPUNIXCOREDWIM
produce la cadena , es big-endian. Si no se produce ninguna cadena o, lo que es más sorprendente, ambas lo hacen, entonces la prueba ha fallado.
Este enfoque funciona porque las constantes "fourcc" calculadas en el programa tienen valores independientes de la máquina, que denotan los mismos enteros independientemente de la endianidad. Su representación de almacenamiento en el archivo de objeto sigue la endianness del sistema de destino, y eso es visible a través de la vista basada en caracteres debajo strings
.
Las dos palabras de protección cero aseguran que la cadena esté aislada. Eso no es estrictamente necesario, pero asegura que la cadena que estamos buscando no esté incrustada en alguna otra cadena, lo que significa que la strings
generará en una línea por sí misma.
PD: la USPELL
macro no hace paréntesis de las inserciones de argumentos porque está diseñada para este propósito específico, no para su reutilización.