Requisito leggermente diverso: ho bisogno di un test come questo in uno script di configurazione della compilazione del programma per determinare se la macchina di destinazione della compilazione è bit o little endian, senza eseguire il codice . Lo script deve depositare #define HAVE_LITTLE_ENDIAN 1
in config.h
un'intestazione, altrimenti #define HAVE_LITTLE_ENDIAN 0
.
La macchina di destinazione della compilazione potrebbe essere diversa dalla macchina di compilazione, poiché potremmo eseguire la compilazione incrociata, il che spiega anche perché il test non deve tentare di eseguire alcun codice compilato. È fuori discussione avere un piccolo programma C con una printf
dichiarazione che sputa la risposta.
Una possibile soluzione è questa. Generiamo un file chiamato conftest.c
che contiene questo:
#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
};
Ora, lo compiliamo conftest.o
usando:
$ /path/to/cross-compiling/cc conftest.c -c
Quindi corriamo:
$ strings conftest.o
PSILXINUEROCMIWD
Se si PSILXINUEROCMIWD
verifica la stringa , la destinazione è little-endian. Se la stringa si LISPUNIXCOREDWIM
verifica, è big-endian. Se non si verifica nessuna stringa o, ancor più sorprendentemente, entrambe le funzioni, il test ha avuto esito negativo.
Questo approccio funziona perché le costanti "fourcc" calcolate nel programma hanno valori indipendenti dalla macchina, che indicano gli stessi numeri interi indipendentemente dall'endianness. La loro rappresentazione di archiviazione nel file oggetto segue l'endianità del sistema di destinazione, ed è visibile tramite la vista basata sui caratteri in strings
.
Le due parole zero guard assicurano che la stringa sia isolata. Ciò non è strettamente necessario, ma garantisce che la stringa che stiamo cercando non sia incorporata in qualche altra stringa, il che significa che la strings
genererà su una riga da sola.
PS la USPELL
macro non è tra parentesi negli inserimenti degli argomenti perché è predisposta per questo scopo specifico, non per il riutilizzo.