Code supportant des ordres d'octets arbitraires, prêt à être placé dans un fichier appelé order32.h
:
#ifndef ORDER32_H
#define ORDER32_H
#include <limits.h>
#include <stdint.h>
#if CHAR_BIT != 8
#error "unsupported char size"
#endif
enum
{
O32_LITTLE_ENDIAN = 0x03020100ul,
O32_BIG_ENDIAN = 0x00010203ul,
O32_PDP_ENDIAN = 0x01000302ul, /* DEC PDP-11 (aka ENDIAN_LITTLE_WORD) */
O32_HONEYWELL_ENDIAN = 0x02030001ul /* Honeywell 316 (aka ENDIAN_BIG_WORD) */
};
static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
{ { 0, 1, 2, 3 } };
#define O32_HOST_ORDER (o32_host_order.value)
#endif
Vous pouvez vérifier les systèmes little endian via
O32_HOST_ORDER == O32_LITTLE_ENDIAN
2 votes
Pourquoi ne pas inclure le même code dans une macro ?
4 votes
Vous ne pouvez pas déterminer l'endiveté de manière portative avec le préprocesseur C seul. Vous voulez aussi
0
au lieu deNULL
dans votre test final, et modifiez l'un des éléments suivantstest_endian
les objets à quelque chose d'autre :-).0 votes
Pourquoi avez-vous besoin d'une macro ?
2 votes
Et pourquoi une macro est-elle nécessaire ? Une fonction en ligne ferait la même chose et est beaucoup plus sûre.
0 votes
S'agit-il d'une énigme ou d'un devoir à faire à la maison ? Normalement, vous ne devriez pas avoir à vous soucier du caractère endiablé de votre plate-forme.
15 votes
@Sharptooth, une macro est intéressante parce que sa valeur peut être connue au moment de la compilation, ce qui signifie que vous pourriez utiliser l'endiannité de votre plateforme pour contrôler l'instanciation des templates, par exemple, ou peut-être même sélectionner différents blocs de code avec une macro.
#if
directive.1 votes
@jamesdlin Lorsque vous écrivez une application réseau ou une application qui exporte des données binaires dans un fichier, il est essentiel de connaître l'endianness et de gérer correctement les conversions. Par exemple, si un serveur Sun SPARC (big endian) et un serveur Intel x86 (little endian) échangent des données binaires, l'un des deux devra convertir les données ; celles-ci seront mal interprétées. Vous pourriez utiliser
ntohl()
,htonl()
,ntohs()
ouhtons()
mais ils ne gèrent que les types de données 32 et 16 bits.1 votes
@DavidM.Syzdek Le format des données sur la fil de fer doit être dans un connu, spécifié format (généralement l'ordre du réseau). Vous faites no Vous devez connaître l'endiveté de votre plate-forme pour écrire dans ce format spécifique ; vous pouvez écrire endian- agnostique en écrivant un octet à la fois (par ex.
fputc((value >> 24) & 0xFF, fp), fputc((value >> 16) & 0xFF, fp)
...)4 votes
C'est vrai, mais inefficace. Si j'ai un processeur little-endian et que j'écris des données little-endian sur le fil ou dans un fichier, je préfère éviter de déballer et de remballer des données sans aucun but. J'avais l'habitude d'écrire des pilotes vidéo pour gagner ma vie. C'est extrêmement Il est important, lorsque l'on écrit des pixels sur une carte vidéo, d'optimiser chaque endroit où l'on peut le faire.