Heim >Backend-Entwicklung >Golang >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.
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ß.
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!