Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Perbezaan penjajaran struktur data dalam Go dan C

Perbezaan penjajaran struktur data dalam Go dan C

WBOY
WBOYke hadapan
2024-02-09 15:51:091048semak imbas

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.

Kandungan soalan

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.

Penyelesaian

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam