Трохи інша вимога: мені потрібен такий тест у скрипті конфігурації побудови програми, щоб визначити, чи є цільова машина компіляції бітною або мало ендіанською, без виконання коду . Сценарій повинен зберігатись #define HAVE_LITTLE_ENDIAN 1
у config.h
заголовку чи іншому #define HAVE_LITTLE_ENDIAN 0
.
Цільова машина компіляції може відрізнятися від машини збирання, оскільки ми можемо перетинати компіляцію, що також пояснює, чому тест не повинен намагатися запустити будь-який компільований код. Немає сумніву, щоб мати невелику програму С із printf
заявою, яка випилює відповідь.
Можливе рішення - це. Ми генеруємо файл, conftest.c
який називається, який містить це:
#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
};
Тепер ми компілюємо це за conftest.o
допомогою:
$ /path/to/cross-compiling/cc conftest.c -c
Потім ми запускаємо:
$ strings conftest.o
PSILXINUEROCMIWD
Якщо рядок PSILXINUEROCMIWD
трапляється, ціль є малопомітною. Якщо рядок LISPUNIXCOREDWIM
трапляється, він є великим ендіаном. Якщо не трапляється жодна рядок або, що ще більше дивно, те й інше, тест не вдався.
Цей підхід працює тому, що константи "чотирьох куб", обчислені в програмі, мають незалежні від машини значення, що позначають однакові цілі числа незалежно від витривалості. Їх представлення на зберігання в файлі об'єктів слід за витримкою цільової системи, і це видно через представлення на основі символів в розділі strings
.
Два слова з нульовим захистом забезпечують ізоляцію рядка. Це не є строго необхідним, але це гарантує, що рядок, яку ми шукаємо, не вбудовується в якусь іншу рядок, тобто означає, що вона strings
виведе її на рядок сама по собі.
PS USPELL
макрос не вкладає в дужки вставки аргументів, оскільки він створений для цієї конкретної мети, а не для повторного використання.