Home > Article > Backend Development > Data structure alignment differences in Go and C
php editor Xigua is here to introduce to you the differences in data structure alignment in Go and C. In programming languages, data structure alignment is a memory alignment method performed to improve memory access efficiency. However, there are some differences between Go and C in terms of data structure alignment. In C language, alignment is controlled through compiler settings, while in Go language, alignment is done automatically by the compiler. This difference can cause memory access errors in Go when code is written in C. Therefore, it is very important for developers to understand the differences in data structure alignment in Go and C.
I have initialized a structure in my C program and attached it to shared memory. The structure is as follows:
#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;
I'm trying to read a structure from another program written in Golang. I calculated the number of bytes taken by each field in C and have an equivalent field in my Golang struct like this:
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 }The size of the
structure (DrvSHMTagStruct
) is 182416 in C and 182412 in Golang (my operating system is based on ARM). So why is there such a difference? They are 4 bytes different and the interesting thing is that they both work fine, reading and writing on the same structure without errors.
As I obviously searched, I learned that C compilers do some data structure alignment during compilation. Therefore, there is a 4-byte difference. But the question is, how can a Golang program correctly read a structure from shared memory, even with a 4-byte difference?
Also, the problem occurs when I run the program on ARM based Linux. They are the same size on x64 Ubuntu.
This is the filling of the last member Instance
. In your C version, it's padded with 7 bytes. In the Go version, it is filled with 3. The difference is the 4 bytes you notice when doing sizeof
on both platforms.
To make them the same, you can use #pragma pack(4)
in the C version or #pragma pack(8)
in the Go version (if it even supports package, search suggests it doesn't) or add a filler as the last member of the Go struct:
Filler1 [7]uint8
The above is the detailed content of Data structure alignment differences in Go and C. For more information, please follow other related articles on the PHP Chinese website!