Rumah >pembangunan bahagian belakang >Golang >Perbezaan penjajaran struktur data dalam Go dan C
editor php Xigua di sini untuk memperkenalkan kepada anda perbezaan dalam penjajaran struktur data dalam Go dan C. Dalam bahasa pengaturcaraan, penjajaran struktur data ialah kaedah penjajaran memori yang dilakukan untuk meningkatkan kecekapan capaian memori. Walau bagaimanapun, terdapat beberapa perbezaan antara Go dan C dari segi penjajaran struktur data. Dalam bahasa C, penjajaran dikawal melalui tetapan pengkompil, manakala dalam bahasa Go, penjajaran dilakukan secara automatik oleh pengkompil. Perbezaan ini boleh menyebabkan ralat capaian memori dalam Go apabila kod ditulis dalam C. Oleh itu, adalah sangat penting bagi pembangun untuk memahami perbezaan dalam penjajaran struktur data dalam Go dan C.
Saya telah memulakan struktur dalam program C saya dan melampirkannya pada memori yang dikongsi. Strukturnya adalah seperti berikut:
#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;
Saya cuba membaca struktur daripada program lain yang ditulis dalam Golang. Saya mengira bilangan bait yang diambil oleh setiap medan dalam C dan mempunyai medan yang setara dalam struct Golang saya seperti ini:
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 }Saiz
struktur (DrvSHMTagStruct
) ialah 182416 dalam C dan 182412 di Golang (sistem pengendalian saya berasaskan ARM). Jadi mengapa terdapat perbezaan sedemikian? Mereka adalah 4 bait berbeza dan perkara yang menarik ialah kedua-duanya berfungsi dengan baik, membaca dan menulis pada struktur yang sama tanpa ralat.
Seperti yang saya cari dengan jelas, saya mengetahui bahawa pengkompil C melakukan beberapa penjajaran struktur data semasa penyusunan. Oleh itu, terdapat perbezaan 4-bait. Tetapi persoalannya ialah, bagaimanakah program Golang boleh membaca struktur daripada memori yang dikongsi dengan betul, walaupun dengan perbezaan 4-bait?
Selain itu, masalah timbul apabila saya menjalankan program pada Linux berasaskan ARM. Mereka adalah saiz yang sama pada x64 Ubuntu.
Ini ialah 4 bait yang diperhatikan apabila ahli terakhir Instance
的填充。在你的 C 版本中,它用 7 个字节填充。在 Go 版本中,它用 3 填充。区别在于您在两个平台上执行 sizeof
ditambah.
Untuk menjadikannya sama, anda boleh menggunakan #pragma pack(4)
或在 Go 版本中使用 #pragma pack(8)
dalam versi C (jika ia menyokong pembungkusan, carian mencadangkan ia tidak) atau tambah pengisi sebagai ahli terakhir struct Go:
Filler1 [7]uint8
Atas ialah kandungan terperinci Perbezaan penjajaran struktur data dalam Go dan C. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!