Ordre des champs lors de l'utilisation d'un champ de bits en C
J'ai une structure du type suivant
typedef struct
{
unsigned int a : 8;
unsigned int b : 6;
unsigned int c : 2;
}x, *ptr;
Ce que je voudrais faire, c'est de changer la valeur du champ c.
Je faire quelque chose comme
x structure = { 0 };
x->c = 1;
Quand je regarde la carte mémoire, je m'attends à trouver 00 01, mais à la place je trouve 00 40.
Il ressemble lors de l'organisation de la deuxième octet, il met c champ le plus bas de l'bits et b champ le plus élevé de bits. J'ai vu cela sur GCC et compilateurs pour Windows.
Pour l'instant, ce que je fais est la suivante, qui fonctionne OK.
unsigned char ptr2 = (unsigned char*) ptr
*(ptr2 + 1) &= 0xFC
*(ptr2 + 1) |= 0x01
Suis-je en regardant la carte mémoire de mal?
Je vous remercie pour votre aide.
Comment afficher le 00 40 de la valeur?
En supposant que
Désolé, le code n'est pas complet ici, j'ai effectué la conversion en unsigned short pour aller de 1 par tous les temps.
J'ai vérifié la carte mémoire dans Visual Studio, et imprimé les valeurs de la variable / champs plus tard.
ok. Le
En supposant que
ptr
détient &structure
(qui n'est pas clair dans votre question) *(ptr+1)
est une marche rapide dans undefined behavior.Désolé, le code n'est pas complet ici, j'ai effectué la conversion en unsigned short pour aller de 1 par tous les temps.
J'ai vérifié la carte mémoire dans Visual Studio, et imprimé les valeurs de la variable / champs plus tard.
ok. Le
*ptr
un type et un ptr
comme une variable jeté ma tête. Je crois que je vois ce que vous faites. ptr
est (maintenant est) un unsigned char*
dans le déréférencement de code.
OriginalL'auteur fashasha | 2013-10-15
Vous devez vous connecter pour publier un commentaire.
C standard permet compilateur de mettre des bits de champs dans un ordre quelconque. Il n'est pas fiable et portable de façon à déterminer l'ordre.
Si vous avez besoin de connaître précisément les positions de bits, il est préférable d'utiliser de la plaine unsigned variable et peu de masquage.
Voici une alternative possible à l'aide de bits-champs:
Ouais, désolé, comme je l'ai mentionné dans la première réponse, j'ai oublié de l'ajouter à la poste. En tout cas, je vous remercie pour la ligne à partir de la norme. Je suppose que l'aide de bits de masquage seront suffisamment de chemin pour configuration les champs. Je suppose que je peux toujours utiliser la structure pour obtenir les valeurs des champs.
La commande de bits ont aucun rapport avec l'endianess?
En relation. Si vous ne
(unsigned)number & 1
, il vous donnera toujours la LSB, et boutisme n'est pas pertinent. Byte-endianness: Si vous inspectez octets denumber
, puis octet, qui a LSB est définie par l'implémentation. Sur little-endian système, LSB peut être trouvé sur le premier octet. Bit-endianness: Il est impossible de connaître l'ordre des bits dans un octet en C. En bref: vous devez Vous préoccuper de byte-edianness si vous écrivez du code qui convertit les données d'octets ou le dos. Vous n'avez pas vraiment besoin de se soucier de bit-boutisme, puisque C n'a pas la capacité de prendre l'adresse du bit.Je réalise que c'est moche, mais est-il un moyen de définir l'ordre de comportement en utilisant GCC spécifiques des macros? Ne compilateurs fournir ce service?
OriginalL'auteur user694733
Je sais que c'est un ancien, mais je voudrais ajouter mes pensées.
Les en-têtes C sont destinés à être utilisable dans tous les objets, ce qui signifie que le compilateur doit être un peu cohérent.
Dans mon expérience, j'ai toujours vu bitfields dans LSB de l'ordre. Cela permettra de mettre les bits MSB->LSB de l'ordre de c:b:un
Les 16 bits, lire dans l'ordre des octets est "00 40". Traduit de Little-endian, c'est une valeur de 16 bits de 0x4000.
C'est:
OriginalL'auteur jrelles
de la mémoire dépend toujours de la structure de la machine sous-jacente (endianness) et sur la stratégie pour l'emballage/organiser la structure du compilateur.
OriginalL'auteur Peter Miehle
Vous définissez une structure C à raw bits à vos risques et périls.
Vous savez que les bits sont et ce qu'ils signifient, de sorte que vous pouvez remplir les champs de la structure. Oui, c'est que le code memcpy, mais il ne cassera pas si quelqu'un ajoute un champ, et si l'aide à faire respecter bits au niveau de la spécificité de la toujours des liens.
OriginalL'auteur Malcolm McLean