2011-01-08 2 views
1

Supposons que je struct Foomeilleure façon de se référer à la taille de la structure (#pragma pack VS taille définie)

struct Foo{ 
    int a; 
    short b; 
    char c; 
}; 

Et je doit écrire ce struct pour n/w tampon. J'ai besoin de connaître la taille de cette structure. Dans mon environnement, sizeof (Foo) renvoie 8, c'est ok, je comprends.

Ce sont deux façons de se référer à la taille exacte que je veux écrire dans la mémoire tampon

1. #define SIZEOF_FOO 7, et utiliser ce lieu de sizeof(Foo)
2. En utilisant #pragma pack je peux utiliser sizeof(Foo) qui sera retour 7

Lequel est le meilleur moyen de le faire, ou Y at-il un autre moyen de le faire?

+0

Quelle est votre intention? Connaître la taille de Foo à tout moment, ou forcer la taille de Foo à une certaine valeur? En effet, sizeof (Foo) renvoie la taille réelle de Foo, et votre espérance d'être à 7 est fausse. Vous devez écrire le nombre réel d'octets dans le tampon, pas le nombre que vous souhaitez que la structure soit. En outre, l'utilisation de constantes ne garantit pas que l'expéditeur et le destinataire ont la même taille de Foo. – mbaitoff

+0

Eh bien, le point est le récepteur est dans le système différent, et il s'attend à ce que les 4 premiers octets soient "une" valeur, et ainsi de suite, 2 octets sont "b", 1 octet suivant est c. C'est le problème quand il ajoute padding 0 après "c" en ce qui concerne la taille d'écriture 8 (de sizeof) au lieu de 7. Et il corrompre le flux de tampon. – Summerpinn

Répondre

2

Si vous devez écrire une telle structure sur un réseau, veuillez utiliser un cadre de protocole ou marshall les données explicitement en utilisant un protocole que vous définissez indépendamment de la structure.

En fonction de la configuration binaire, les détails d'une structure causeront probablement de la douleur sur la route.

J'ai entendu de bonnes choses sur Google Protocol Buffers et Boost serialization, mais je n'ai pas utilisé non plus.

J'ai traité un protocole défini dans un document, et sorti les données selon ce protocole en utilisant des routines de marshaling personnalisées, ou utilisé une description IDL (qui ressemble à une structure C annotée utilisée pour générer un code générateur qui crée les routines de sérialisation/désérialisation). De cette façon, vous (ou le framework de protocole) contrôlez l'utilisation de padding indépendamment de ce que fait le compilateur à la structure. Notez que vous utilisez un framework de protocole, vous avez généralement besoin de l'utiliser aux deux extrémités (ce qui peut être un problème si l'autre nœud est hors de votre contrôle ou un périphérique embarqué que le framework ne supporte pas, par exemple).

0

La directive #pragma pack modifie la règle d'alignement actuelle pour les membres de structures suivant la directive. Par conséquent, il affecte la taille des structures définies après le pragma!

Vous n'avez probablement pas besoin de cela. Utilisez simplement sizeof(Foo) où vous voulez connaître la taille de votre structure. Et n'écrivez pas de pragmas, car ils sont utilisés dans certains cas particuliers!

Vous pouvez voir ces liens pour en savoir en détails sur pragma:

GCC - Structure-Packing Pragmas
MSVC++ - Pack
pragma pack

0

Cette question est sérieusement erronée. La taille de Foo est toujours celle sizeof(Foo). Ne supposez pas, ne pas utiliser un vœu pieux, utilisez sizeof.

En fait, je m'attendrais à sizeof(Foo) être 12, alignant tout sur une limite de 4 octets.

De toute façon, la bonne nouvelle est que sizeof est résolu au moment de la compilation, et n'a absolument aucun impact sur les performances. Donc, il n'y a aucune raison de ne pas l'utiliser.

#define SIZEOF_FOO (sizeof(Foo)) 
+0

Juste curieux: pourquoi vous attendez-vous à ce que ce soit 9? – Mehrdad

+0

Je m'attends à ce que 'sizeof (Foo)' soit 8, car 'short' et 'char' se logeraient dans une limite de 4 octets! – Nawaz

+0

J'ai d'abord eu 12, mais réduit à 9 parce que j'étais stupide. Je l'ai réédité à 12. –

0

Je conseillerais d'écrire la structure en écrivant séquentiellement ses membres. Par exemple. vous pouvez utiliser la sérialisation boost.

Ceci séparera la représentation de la structure dans la mémoire de l'application du format utilisé pour la transmission.

0

#define SIZEOF_FOO 7 sans utiliser #pragma pack ne doit pas être utilisé du tout. La raison étant, lorsque vous appelez send (ou toute autre fonction équivalente) en passant une variable de votre type struct et passez la taille des données à 7, la fonction d'envoi n'enverra que les premiers 7 octets de données, et lorsque vous recevrez ces données au À l'autre extrémité, vous allez certainement gâcher beaucoup de choses dans votre code. L'utilisation des directives #pragma pack va changer l'alignement du membre de votre structure et vous économiserez certainement quelques octets de données sur le transfert réseau, mais si vous pensez en termes d'optimisation/performance, ces quelques octets sont négligeables. Bien que, la plupart des applications (que j'ai vues) emploient #pragma pack pour emballer des membres de structure, mais cela dépend totalement de votre condition. Un problème majeur avec l'utilisation d'un #define SIZEOF_FOO 7 est que, si vous portez votre code sur une autre plateforme/architecture, la taille réelle de votre structure pourrait ne pas être la même (7 octets) et vous devrez alors utiliser une plate-forme macro dépendante ou trouver une autre alternative. En bref, vous devez toujours utiliser sizeof au lieu d'utiliser #define SIZEOF_FOO.

Questions connexes