Nieco inne wymaganie: Potrzebuję takiego testu w skrypcie konfiguracyjnym kompilacji programu, aby ustalić, czy docelowa maszyna do kompilacji jest bitowa czy mała, bez wykonywania kodu . Skrypt musi zostać złożony #define HAVE_LITTLE_ENDIAN 1w config.hnagłówku, w przeciwnym razie #define HAVE_LITTLE_ENDIAN 0.
Komputer docelowy kompilacji może różnić się od maszyny kompilacji, ponieważ możemy kompilować się wzajemnie, co również wyjaśnia, dlaczego test nie może próbować uruchomić żadnego skompilowanego kodu. Nie ma mowy o małym programie C z printfinstrukcją, która wyrzuca odpowiedź.
Możliwym rozwiązaniem jest to. Generujemy plik o nazwie, conftest.cktóry zawiera:
#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
};
Teraz kompilujemy to conftest.oza pomocą:
$ /path/to/cross-compiling/cc conftest.c -c
Następnie uruchamiamy:
$ strings conftest.o
PSILXINUEROCMIWD
Jeśli ciąg PSILXINUEROCMIWDwystąpi, celem jest little-endian. Jeśli ciąg LISPUNIXCOREDWIMwystąpi, jest to big-endian. Jeśli nie wystąpi żaden ciąg znaków lub, co bardziej zaskakujące, oba wystąpią, oznacza to, że test się nie powiódł.
Takie podejście działa, ponieważ obliczone w programie stałe „fourcc” mają wartości niezależne od maszyny, oznaczające te same liczby całkowite niezależnie od endianowości. Ich reprezentacja pamięci w pliku obiektowym jest zgodna z endianizmem systemu docelowego i jest to widoczne w widoku opartym na znakach pod strings.
Dwa zerowe słowa zabezpieczające zapewniają, że ciąg jest izolowany. Nie jest to absolutnie konieczne, ale zapewnia, że szukany ciąg nie jest osadzony w innym ciągu, co oznacza, że stringswyprowadzi go sam w wierszu.
PS USPELLmakro nie nawiasy wstawia argumentów, ponieważ jest spreparowane do tego konkretnego celu, a nie do ponownego użycia.