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 1en un config.hencabezado, 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 printfdeclaración que escupe la respuesta.
Una posible solución es esta. Generamos un archivo llamado conftest.cque 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.ousar:
$ /path/to/cross-compiling/cc conftest.c -c
Luego corremos:
$ strings conftest.o
PSILXINUEROCMIWD
Si se PSILXINUEROCMIWDproduce la cadena , el objetivo es little-endian. Si se LISPUNIXCOREDWIMproduce 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 stringsgenerará en una línea por sí misma.
PD: la USPELLmacro no hace paréntesis de las inserciones de argumentos porque está diseñada para este propósito específico, no para su reutilización.