2016-09-01 1 views
6

J'ai la série de structures suivante.Syntaxe correcte pour l'utilisation de l'union avec des champs de bits dans une structure

struct FooWord1 
{ 
    unsigned int Fill  : 8; 
    unsigned int someData1 : 18; 
    unsigned int someData2 : 6; 
}; 

struct FooWord2 
{ 
    unsigned int Fill  : 8; 
    union 
    { 
     unsigned int A_Bit : 1; 
     unsigned int B_Bit : 1; 
    }; 
    unsigned int someData3 : 23; 
}; 

struct Foo_Data 
{ 
    FooWord1 fooWord1; 
    FooWord2 fooWord2; 
    FooWord3 fooWord3; // similar to FooWord1 
    FooWord4 fooWord4; // similar to FooWord1 
    FooWord5 fooWord5; // similar to FooWord1 
}; 

Foo_Data fooArray[SIZE]; 

données est copié dans fooArray octet par octet d'un message réseau. Nous obtenons les données que nous attendons dans someData3 si nous n'utilisons pas une union avec le champ de 1 bit (A_bit et B_bit), mais dès que nous mettons dans l'union, les mots obtiennent "off" par 2 mots.

Nous souhaitons utiliser une union parce que ces structures sont utilisées pour différents types de messages, mais la signification de A_Bit et B_Bit est différente pour différents messages. Nous pourrions juste utiliser un commentaire, mais ce serait bien de le faire en code.

Qu'est-ce que je fais mal?

+1

Vous semblez vous attendre à ce que le syndicat n'occupe qu'un seul bit. Ça ne va pas marcher. 'FooWord2' a trois membres, dont un est une union (anonyme), pas un champ de bits, donc ces trois membres ne seront pas emballés ensemble. Le fait que l'union contienne à son tour des champs de bits n'est pas pertinent. –

+0

Si vous souhaitez utiliser des noms différents pour faire référence à ce bit, utilisez des macros. – Barmar

+0

Note de côté: avec votre code actuel, il ne semble pas nécessaire d'avoir un 'union', car tous les champs sont identiques. –

Répondre

0

La réponse se trouve dans les commentaires à la question d'origine. Fill, le union, et someData3 se terminera tous dans des mots séparés, parce que le union commence un nouveau mot dans la structure.

0

Vous pouvez essayer ceci:

struct FooWord2 
{ 
    union 
    { 
     struct 
     { 
      unsigned int Fill  : 8; 
      unsigned int A_Bit  : 1; 
      unsigned int someData3 : 23; 
     }; 
     struct 
     { 
      unsigned int  : 8; 
      unsigned int B_Bit : 1; 
     }; 
    }; 
}; 

besoin de mentionner: selon cette answer, structs anonymes ne sont pas C++ standard, mais extension. GCC permet, MSVC – aussi loin que je me souviens – aussi. LLVM? Pas sûr, mais aussi souvent proche de GCC, le supposerait aussi.

En norme sont en conformité des bibliothèques, ils Ofen d'utiliser des macros pour obtenir l'effet, comme ceci:

struct FooWord2 
{ 
    unsigned int Fill  : 8; 
    unsigned int A_Bit  : 1; 
    unsigned int someData3 : 23; 
}; 
#define B_Bit A_Bit 

Juste explication: Avec votre code d'origine, vous avez obtenu cet effet:

  • Remplissez commence un nouveau champ de bit
  • À l'intérieur de l'union, un nouveau champ de bit est démarré ici, je ne sais pas si cela crée un seul bit ou éventuellement un champ de bit avec deux entrées. Peut-être que n'importe qui peut faire la lumière sur ce que la norme indique ...
  • En fermant l'union, le champ de bits est fini aussi.
  • someData3 commence alors un nouveau champ de bits

Ainsi, les décalages que vous voulez éviter.