Dữ liệu được sắp xếp và truy cập trong bộ nhớ máy tính bằng cách sử dụng Căn chỉnh dữ liệu. Trong đó có hai vấn đề liên quan
- Alignment
- Padding
Khi một hoạt động viết được thực hiện bằng máy tính, Nó thường viết trong bội số của 4 byte (cho các hệ thống 32 bit). Một lý do cho hành động này là mục tiêu tăng hiệu suất.Vì vậy, khi bạn đang viết bất kỳ cấu trúc dữ liệu nào, có biến số 1 byte đầu tiên và sau đó dữ liệu biến 4 byte, nó sẽ làm đệm sau dữ liệu byte 1 đầu tiên để căn chỉnh nó trên ranh giới 32 bit.
struct {
union {
struct {
uint32_t messageID : 26;
uint8_t priority : 3;
} __attribute__ ((packed));
uint32_t rawID : 29;
} __attribute__ ((packed));
uint8_t canFlags : 3;
} __attribute__ ((packed)) idSpecial;
Bây giờ trong cấu trúc dữ liệu ở trên bạn đang sử dụng __attribute__ ((packed))
có nghĩa là không có đệm. Vì vậy, uint32_t là 4 byte, nhưng bạn đang saing nó có 26 bit và 3 bit cho ưu tiên. Bây giờ khi bạn có cả hai biến trong một cấu trúc để nó sẽ dự trữ 32 bit thay vì 29 để thông tin cấu trúc đầu tiên của bạn được gán cho các ranh giới.
Bây giờ cho canFlags Nó sẽ cần một byte khác. Vì vậy, làm cho 5 byte thay vì 4 byte thay vì 4.
Nguồn
2015-04-01 07:43:39
có thể trùng lặp của [Cấu trúc và Liên minh trong C, xác định kích thước và truy cập thành viên] (http://stackoverflow.com/questions/3380118/structures-and-unions-in-c -determining-size-and-access-members) –
@DavidTitarenco: Tôi không nghĩ rằng bài đăng cụ thể đó tốt cho bitfields. Nó sẽ không làm tôi ngạc nhiên nếu điều này đã được trả lời ở nơi khác tho '. –
Người trả lời cần chú ý rằng OP đang sử dụng [không chuẩn __attribute__ ((đóng gói)) '] (https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html) GCC mở rộng để tránh đệm . Vì vậy, nói rằng trình biên dịch được phép chèn đệm là không chính xác - khi '__attribute __ ((đóng gói))' được sử dụng, GCC sẽ tổ chức cấu trúc để tránh đệm (làm cho truy cập đắt hơn trên nền tảng không hỗ trợ đọc không đồng nhất). – user4815162342