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 1
w config.h
nagłó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 printf
instrukcją, która wyrzuca odpowiedź.
Możliwym rozwiązaniem jest to. Generujemy plik o nazwie, conftest.c
któ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.o
za pomocą:
$ /path/to/cross-compiling/cc conftest.c -c
Następnie uruchamiamy:
$ strings conftest.o
PSILXINUEROCMIWD
Jeśli ciąg PSILXINUEROCMIWD
wystąpi, celem jest little-endian. Jeśli ciąg LISPUNIXCOREDWIM
wystą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 strings
wyprowadzi go sam w wierszu.
PS USPELL
makro nie nawiasy wstawia argumentów, ponieważ jest spreparowane do tego konkretnego celu, a nie do ponownego użycia.