65 votes

Détermination de l'endianité au moment de la compilation

Existe-t-il un moyen sûr et portable de déterminer (pendant la compilation) l’endianité de la plate-forme sur laquelle mon programme est compilé? J'écris en C.

[EDIT] Merci pour les réponses, j'ai décidé de rester avec la solution d'exécution!

30voto

birryree Points 29165

C'est pour le moment de la compilation, la vérification de

Vous pouvez utiliser les informations de l'augmentation de l'en-tête du fichier endian.hpp, qui couvre de nombreuses plates-formes.

edit pour le contrôle d'exécution

bool isLittleEndian()
{
    short int number = 0x1;
    char *numPtr = (char*)&number;
    return (numPtr[0] == 1);
}

Créer un entier, et de lire son premier octet (octet le moins significatif). Si cet octet est 1, alors le système est en little endian, sinon c'est le big-endian.

modifier la Pensée à ce sujet

Oui, vous pouvez rencontrer un problème potentiel dans certaines plates-formes (ne peut pas penser à tout) où sizeof(char) == sizeof(short int). Vous pouvez utiliser une largeur fixe multi-octets types intégraux disponibles en <stdint.h>, ou si votre plate-forme ne l'a pas, encore une fois, vous pourriez adapter un coup de pouce de l'en-tête de votre utilisation: stdint.hpp

16voto

R.. Points 93718

Avec C99, vous pouvez effectuer le contrôle comme suit:

 #define I_AM_LITTLE (((union { unsigned x; unsigned char c; }){1}).c)
 

Des conditions telles que if (I_AM_LITTLE) seront évaluées lors de la compilation et permettront au compilateur d'optimiser des blocs entiers.

Je n'ai pas la référence exacte pour savoir s'il s'agit à proprement parler d'une expression constante en C99 (ce qui lui permettrait d'être utilisée dans les initialiseurs pour les données de durée de stockage statique), mais sinon, c'est la meilleure chose à faire.

11voto

Daniel Băluţă Points 940

Lecture intéressante de la FAQ C :

Vous ne pouvez probablement pas. Les techniques habituelles de détection de l’endianité impliquent des pointeurs ou des tableaux de caractères, voire des unions, mais l’arithmétique des préprocesseurs n’utilise que des entiers longs et il n’existe pas de concept d’adressage. Une autre possibilité tentante est quelque chose comme

   #if 'ABCD' == 0x41424344
 

mais ce n'est pas fiable non plus.

7voto

towi Points 5192

Je voudrais élargir les réponses pour fournir une fonction constexpr pour C ++

 union Mix {
    int sdat;
    char cdat[4];
};
static constexpr Mix mix { 0x1 };
constexpr bool isLittleEndian() {
    return mix.cdat[0] == 1;
}
 

Puisque mix est constexpr aussi, c'est aussi le temps de compilation et peut être utilisé en constexpr bool isLittleEndian() . Devrait être sécuritaire d'utiliser.

6voto

pr1268 Points 598

Pas pendant la compilation, mais peut-être pendant l'exécution. Voici une fonction C que j'ai écrite pour déterminer l'endianité:

 /*  Returns 1 if LITTLE-ENDIAN or 0 if BIG-ENDIAN  */
#include <inttypes.h>
int endianness()
{
  union { uint8_t c[4]; uint32_t i; } data;
  data.i = 0x12345678;
  return (data.c[0] == 0x78);
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X