Requisito ligeiramente diferente: preciso de um teste como este em um script de configuração de compilação do programa para determinar se a máquina de destino de compilação é pouco ou pouco endian, sem executar código . O script deve depositar #define HAVE_LITTLE_ENDIAN 1
em um config.h
cabeçalho, ou então #define HAVE_LITTLE_ENDIAN 0
.
A máquina de destino de compilação pode ser diferente da máquina de compilação, pois podemos fazer uma compilação cruzada, o que também explica por que o teste não deve tentar executar nenhum código compilado. Está fora de cogitação ter um pequeno programa C com uma printf
declaração que cuspa a resposta.
Uma solução possível é essa. Geramos um arquivo chamado conftest.c
que contém este:
#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
};
Agora, compilamos isso para conftest.o
usar:
$ /path/to/cross-compiling/cc conftest.c -c
Então nós corremos:
$ strings conftest.o
PSILXINUEROCMIWD
Se a string PSILXINUEROCMIWD
ocorrer, o destino é little-endian. Se a string LISPUNIXCOREDWIM
ocorrer, é big-endian. Se nenhuma string ocorrer ou, ainda mais surpreendente, as duas ocorrerem, o teste falhou.
Essa abordagem funciona porque as constantes "fourcc" calculadas no programa têm valores independentes da máquina, denotando os mesmos números inteiros, independentemente da endianidade. Sua representação de armazenamento no arquivo de objeto segue o endianness do sistema de destino e é visível através da exibição baseada em caracteres em strings
.
As duas palavras de proteção zero garantem que a string seja isolada. Isso não é estritamente necessário, mas garante que a sequência que estamos procurando não seja incorporada em outra sequência, o que significa que strings
a saída será feita em uma linha por si só.
PS, a USPELL
macro não coloca parênteses nas inserções de argumento, porque é criada para esse fim específico, não para reutilização.