2010-01-20 25 views
2

Je réalise qu'en général les normes C et C++ donnent beaucoup de latitude aux rédacteurs de compilateurs. Mais en particulier, il garantit que les types de POD comme les membres de la structure C doivent être mis en mémoire dans le même ordre que dans la définition des structures, et la plupart des compilateurs fournissent des extensions permettant de corriger l'alignement des membres. Donc, si vous aviez un en-tête qui définissait une structure et spécifiait manuellement l'alignement de ses membres, puis compiliez deux applications avec des compilateurs différents en utilisant l'en-tête, une application ne devrait-elle pas pouvoir écrire une instance de la structure en mémoire partagée et l'autre application être en mesure de le lire sans erreurs?Est-il possible de partager une structure C en mémoire partagée entre des applications compilées avec différents compilateurs?

Je suppose cependant que la taille des types contenus est cohérente entre deux compilateurs sur la même architecture (elle doit être la même plate-forme déjà puisque nous parlons mémoire partagée). Je me rends compte que cela n'est pas toujours vrai pour certains types (par exemple long ou long dans GCC et MSVC 64 bits) mais de nos jours il y a des types uint16_t, uint32_t, etc., et float et double sont spécifiés par les normes IEEE.

+0

Les anciennes bibliothèques de liens dynamiques ne le font-elles pas tous les jours? Il ne doit pas être la mémoire partagée, les structures entre deux bibliothèques ou une bibliothèque et l'application compilée indépendamment face à la même question. La bibliothèque peut être compilée avec PIC, mais cela ne change pas la disposition des structures. – Ioan

+0

Lorsque les bibliothèques partagent le même ABI. Cela est généralement vrai pour les bibliothèques C compilées avec des compilateurs différents mais pas C++. –

Répondre

2

Tant que vous pouvez garantir la même mise en page de mémoire exacte, y compris les compensations et les types de données ont les mêmes tailles entre les 2 compilateurs alors oui cela est très bien. Parce qu'à ce stade, la structure est identique en ce qui concerne l'accès aux données.

+0

Cela ressemble plus à un non. – Trent

+0

@Trent, Cela dépend, si vous pouvez faire ces garanties avec des pragmas horribles ou des cas de coin de la langue alors assurez-vous que cela fonctionne. Faire cette garantie est très difficile si à mon humble avis – JaredPar

+0

@Trent: C'est à peu près la même réponse "oui mais" que pour l'utilisation de structs pour lire/écrire des données sur le réseau. L'utilisation d'une structure pour représenter les données sérialisées/marshallées est un détail de votre application qui pourrait être pratique si vous pouvez garantir que la structure est correcte. Les données binaires entre différentes implémentations C devraient probablement être considérées comme «sérialisées»: qu'elles soient partagées sur le réseau ou dans la RAM partagée, les mêmes préoccupations s'appliquent aux types et à la mise en page qui peuvent ne pas correspondre. Un tableau et un flux peuvent tous deux être considérés comme une séquence de char. –

0

La mémoire façon est mis en place est importante, en plus de la taille de type de données si vous avez besoin struct de la bibliothèque 1 compilé par le compilateur 1 à utiliser dans la bibliothèque 2 compilé par le compilateur 2.

0

Il est en effet possible, Il suffit de s'assurer que tous les compilateurs impliqués génèrent la même structure de données à partir du même code. Une façon de tester ceci est d'écrire un exemple de programme qui crée une structure et l'écrit dans un fichier binaire. Ouvrez les fichiers résultants dans un éditeur hexadécimal et vérifiez qu'ils sont identiques. Vous pouvez également convertir la structure en un tableau de uint8_t et vider les octets individuels à l'écran.

Une façon de vous assurer que les tailles de données sont les mêmes est d'utiliser des types de données comme int16_t (de stdint.h) au lieu d'une ancienne int simple qui peut changer la taille entre les compilateurs (bien que ce soit rare sur deux compilateurs cours d'exécution sur la même plate-forme).

Ce n'est pas aussi difficile que cela puisse paraître. Il existe de nombreuses bibliothèques pré-compilées qui peuvent être utilisées avec plusieurs compilateurs. L'essentiel est de construire un programme de test qui vous permettra de vérifier que les deux compilateurs traitent la structure de manière égale.

1

Oui, bien sûr. Je l'ai fait plusieurs fois. Les problèmes et les solutions sont les mêmes, que le code mélangé soit compilé et lié ensemble, ou lors de la transmission de données au format struct entre les machines.

Dans les mauvais jours, ce souvent eu lieu lors de l'intégration MS C et presque tout le reste: Borland Turbo C. décembre VAX C, Greenhills C.

La partie la plus facile est d'obtenir le nombre d'octets pour différents types de données être d'accord. Par exemple short sur un compilateur 32 bits d'un côté étant le même que int sur un compilateur 16 bits à l'autre extrémité. Étant donné que le code source commune de déclarer des structures est généralement une bonne chose, un certain nombre de to-the-point de déclarations sont utiles:

typedef signed long  s32; 
typedef signed short s16; 
typedef signed char  s8; 
typedef unsigned long u32; 
typedef unsigned short u16; 
typedef unsigned char u8; 
... 

Microsoft C est le plus ennuyeux. Sa valeur par défaut est d'aligner les membres sur l'alignement 16 bits, et peut-être plus avec le code 64 bits. Les autres compilateurs sur x86 ne remplissent pas les membres.

Il peut sembler le décalage code devrait être le prochain octet après type, mais il pourrait y avoir un octet de remplissage inséré entre les deux. Le correctif est généralement

#ifdef _MSC_VER // if it's any Microsoft compiler 
#pragma pack(1) // byte align structure members--that is, no padding 
#endif 

Il existe également une option de ligne de commande du compilateur pour faire de même.

0

Reportez-vous aux manuels de votre compilateur.

la plupart des compilateurs fournissent des extensions vous permettant de corriger l'alignement des membres

Êtes-vous vous limiter à ces compilateurs et un style #pragma align mutuellement compatibles? Si c'est le cas, la sécurité est dictée par leurs spécifications. Dans l'intérêt de la portabilité, il vaut peut-être mieux abandonner #pragma align en s'appuyant sur votre ABI, ce qui peut fournir une norme «raisonnable» pour la conformité de tous les compilateurs de votre plate-forme. Comme les normes C et C++ permettent n'importe quelle méthodologie de mise en page de structure déterministe, elles sont essentiellement non pertinentes.