Heim  >  Artikel  >  Backend-Entwicklung  >  Unterschiede in der Datenstrukturausrichtung in Go und C

Unterschiede in der Datenstrukturausrichtung in Go und C

WBOY
WBOYnach vorne
2024-02-09 15:51:091100Durchsuche

Unterschiede in der Datenstrukturausrichtung in Go und C

php-Editor Xigua ist hier, um Ihnen die Unterschiede in der Datenstrukturausrichtung in Go und C vorzustellen. In Programmiersprachen ist die Datenstrukturausrichtung eine Speicherausrichtungsmethode, die durchgeführt wird, um die Effizienz des Speicherzugriffs zu verbessern. Es gibt jedoch einige Unterschiede zwischen Go und C hinsichtlich der Datenstrukturausrichtung. In der C-Sprache wird die Ausrichtung über die Compiler-Einstellungen gesteuert, während in der Go-Sprache die Ausrichtung automatisch vom Compiler erfolgt. Dieser Unterschied kann in Go zu Speicherzugriffsfehlern führen, wenn Code in C geschrieben wird. Daher ist es für Entwickler sehr wichtig, die Unterschiede in der Datenstrukturausrichtung in Go und C zu verstehen.

Frageninhalt

Ich habe in meinem C-Programm eine Struktur initialisiert und an den Shared Memory angehängt. Der Aufbau ist wie folgt:

#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;

Ich versuche, eine Struktur aus einem anderen in Golang geschriebenen Programm zu lesen. Ich habe die Anzahl der Bytes berechnet, die jedes Feld in C einnimmt, und habe in meiner Golang-Struktur ein entsprechendes Feld wie folgt:

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
}
Die Größe von

structure (DrvSHMTagStruct) beträgt 182416 in C und 182412 in Golang (mein Betriebssystem basiert auf ARM). Warum gibt es also einen solchen Unterschied? Sie unterscheiden sich um 4 Byte und das Interessante ist, dass beide gut funktionieren und ohne Fehler in derselben Struktur lesen und schreiben.

Als ich offensichtlich gesucht habe, habe ich erfahren, dass C-Compiler während der Kompilierung eine gewisse Datenstrukturausrichtung vornehmen. Daher gibt es einen Unterschied von 4 Byte. Die Frage ist jedoch: Wie kann ein Golang-Programm eine Struktur aus dem gemeinsam genutzten Speicher korrekt lesen, selbst mit einem Unterschied von 4 Byte?

Außerdem tritt das Problem auf, wenn ich das Programm unter ARM-basiertem Linux ausführe. Unter x64-Ubuntu sind sie gleich groß.

Workaround

Dies sind die 4 Bytes, die beim Hinzufügen des letzten Mitglieds Instance 的填充。在你的 C 版本中,它用 7 个字节填充。在 Go 版本中,它用 3 填充。区别在于您在两个平台上执行 sizeof festgestellt wurden.

Um sie gleich zu machen, können Sie #pragma pack(4) 或在 Go 版本中使用 #pragma pack(8) in der C-Version verwenden (wenn sie das Packen überhaupt unterstützt, deutet die Suche darauf hin, dass dies nicht der Fall ist) oder einen Füller als letztes Mitglied der Go-Struktur hinzufügen:

Filler1     [7]uint8

Das obige ist der detaillierte Inhalt vonUnterschiede in der Datenstrukturausrichtung in Go und C. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen