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 1em um config.hcabeç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 printfdeclaração que cuspa a resposta.
Uma solução possível é essa. Geramos um arquivo chamado conftest.cque 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.ousar:
$ /path/to/cross-compiling/cc conftest.c -c
Então nós corremos:
$ strings conftest.o
PSILXINUEROCMIWD
Se a string PSILXINUEROCMIWDocorrer, o destino é little-endian. Se a string LISPUNIXCOREDWIMocorrer, é 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 stringsa saída será feita em uma linha por si só.
PS, a USPELLmacro não coloca parênteses nas inserções de argumento, porque é criada para esse fim específico, não para reutilização.