Maison > Article > développement back-end > Différences d’alignement de la structure des données dans Go et C
l'éditeur php Xigua est là pour vous présenter les différences d'alignement de la structure des données en Go et C. Dans les langages de programmation, l'alignement de la structure des données est une méthode d'alignement de la mémoire utilisée pour améliorer l'efficacité de l'accès à la mémoire. Cependant, il existe quelques différences entre Go et C en termes d'alignement de la structure des données. En langage C, l'alignement est contrôlé via les paramètres du compilateur, tandis qu'en langage Go, l'alignement est effectué automatiquement par le compilateur. Cette différence peut provoquer des erreurs d’accès mémoire dans Go lorsque le code est écrit en C. Par conséquent, il est très important que les développeurs comprennent les différences d’alignement de la structure des données en Go et en C.
J'ai initialisé une structure dans mon programme C et je l'ai attachée à la mémoire partagée. La structure est la suivante :
#define DrvMaxTag 1024 #define DrvMaxStr 128 #define StructLEN 32 typedef struct TagTypeStruct { unsigned char IO; unsigned char Drv; unsigned char Class; unsigned char Group; }TagTypeStruct; typedef struct IEC_DT { long int tv_Sec; long int tv_nSec; }IEC_DT; typedef struct DrvSHMTagStruct { char TagName[DrvMaxTag][DrvMaxStr]; double TagValue[DrvMaxTag]; double OldValue[DrvMaxTag]; unsigned int TagStatus[DrvMaxTag]; unsigned int OldStatus[DrvMaxTag]; long long TagControl[DrvMaxTag]; IEC_DT TagValueDT[DrvMaxTag]; TagTypeStruct TagType[DrvMaxTag]; int DrvAddr[DrvMaxTag]; unsigned char LogFlag[DrvMaxTag]; unsigned char Freeze[DrvMaxTag]; int LogicState; char DrvPath[DrvMaxStr]; int TagQuantity; unsigned char Instance; }DrvSHMTagStruct;
J'essaie de lire une structure d'un autre programme écrit en Golang. J'ai calculé le nombre d'octets pris par chaque champ en C et j'ai un champ équivalent dans ma structure Golang comme ceci :
const StructLEN = 32 const DrvMaxTag = 1024 const DrvMaxStr = 128 type TagTypeStruct struct { IO uint8 Drv uint8 Class uint8 Group uint8 } type IEC_DT struct { tv_Sec int32 tv_nSec int32 } type DrvSHMTagStruct struct { TagName [DrvMaxTag][DrvMaxStr]byte TagValue [DrvMaxTag]float64 OldValue [DrvMaxTag]float64 TagStatus [DrvMaxTag]uint32 OldStatus [DrvMaxTag]uint32 TagControl [DrvMaxTag]int64 TagValueDT [DrvMaxTag]IEC_DT TagType [DrvMaxTag]TagTypeStruct DrvAddr [DrvMaxTag]int32 RetainFlag [DrvMaxTag]uint8 Freeze [DrvMaxTag]uint8 LogicState int32 DrvPath [DrvMaxStr]uint8 TagQuantity int32 Instance uint8 }La taille de
structure (DrvSHMTagStruct
) est 182416 en C et 182412 en Golang (mon système d'exploitation est basé sur ARM). Alors pourquoi y a-t-il une telle différence ? Ils sont différents de 4 octets et ce qui est intéressant est qu'ils fonctionnent tous les deux correctement, lisant et écrivant sur la même structure sans erreur.
En cherchant évidemment, j'ai appris que les compilateurs C effectuent un certain alignement de la structure des données lors de la compilation. Il existe donc une différence de 4 octets. Mais la question est : comment un programme Golang peut-il lire correctement une structure à partir de la mémoire partagée même s'il y a une différence de 4 octets ?
De plus, le problème survient lorsque j'exécute le programme sur Linux basé sur ARM. Ils ont la même taille sur Ubuntu x64.
Il s'agit des 4 octets remarqués lorsque le dernier membre Instance
的填充。在你的 C 版本中,它用 7 个字节填充。在 Go 版本中,它用 3 填充。区别在于您在两个平台上执行 sizeof
est ajouté.
Pour les rendre identiques, vous pouvez utiliser #pragma pack(4)
或在 Go 版本中使用 #pragma pack(8)
dans la version C (si elle prend même en charge le packaging, la recherche suggère que ce n'est pas le cas) ou ajouter un remplissage comme dernier membre de la structure Go :
Filler1 [7]uint8
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!