Ý nghĩa của “__attribute __ ((đóng gói, căn chỉnh (4)))”


122

Nó là ngôn ngữ C. Nó được viết rằng:

typedef struct __attribute__((packed, aligned(4))) Ball {
    float2 delta;
    float2 position;
    //float3 color;
    float size;
    //int arcID;
    //float arcStr;
} Ball_t;
Ball_t *balls;

Vui lòng cho tôi biết ý nghĩa của nó là gì và cách sử dụng từ khóa này.


4
Đó là một "loại thuộc tính" .. (Tôi thấy điều này với "C thuộc tính đóng gói" trong Google Chắc chắn những người khác ít nhất có thể làm tốt.!)

1
Xem câu hỏi này - mặc dù với aligned(4)bạn có lẽ không có nhiều điều để lo lắng.
Keith Thompson

Câu trả lời:


157

Trước khi trả lời, tôi xin cung cấp cho bạn một số dữ liệu từ Wiki


Căn chỉnh cấu trúc dữ liệu là cách dữ liệu được sắp xếp và truy cập trong bộ nhớ máy tính. Nó bao gồm hai vấn đề riêng biệt nhưng có liên quan đến nhau: căn chỉnh dữ liệuđệm cấu trúc dữ liệu .

Khi một máy tính hiện đại đọc từ hoặc ghi vào một địa chỉ bộ nhớ, nó sẽ thực hiện việc này theo các phần có kích thước từ (ví dụ: phần 4 byte trên hệ thống 32 bit). Căn chỉnh dữ liệu có nghĩa là đặt dữ liệu ở khoảng trống bộ nhớ bằng bội số của kích thước từ, điều này làm tăng hiệu suất của hệ thống do cách CPU xử lý bộ nhớ.

Để căn chỉnh dữ liệu, có thể cần phải chèn một số byte vô nghĩa giữa phần cuối của cấu trúc dữ liệu cuối cùng và phần bắt đầu của phần tiếp theo, đó là phần đệm cấu trúc dữ liệu .


gcc cung cấp chức năng vô hiệu hóa phần đệm cấu trúc. nghĩa là để tránh những byte vô nghĩa này trong một số trường hợp. Hãy xem xét cấu trúc sau:

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}sSampleStruct;

sizeof(sSampleStruct)sẽ là 12 chứ không phải 8. Vì cấu trúc đệm. Theo mặc định, Trong X86, các cấu trúc sẽ được đệm vào căn chỉnh 4 byte:

typedef struct
{
     char Data1;
     //3-Bytes Added here.
     int Data2;
     unsigned short Data3;
     char Data4;
     //1-byte Added here.

}sSampleStruct;

Chúng tôi có thể sử dụng __attribute__((packed, aligned(X)))để nhấn mạnh khoảng đệm có kích thước (X) cụ thể. X nên là lũy thừa của hai. Tham khảo tại đây

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}__attribute__((packed, aligned(1))) sSampleStruct;  

vì vậy thuộc tính gcc được chỉ định ở trên không cho phép đệm cấu trúc. vì vậy kích thước sẽ là 8 byte.

Nếu bạn muốn làm điều tương tự cho tất cả các cấu trúc, chỉ cần chúng ta có thể đẩy giá trị căn chỉnh vào ngăn xếp bằng cách sử dụng #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)

6
Nếu bộ nhớ lưu trữ dữ liệu ở dạng khối 4 byte thì tại sao nó không thêm 2 byte đệm vào đoạn ngắn không dấu (độ dài 2 byte của nó)? hay trình biên dịch chỉ thêm các byte đệm vào thành viên đầu tiên và cuối cùng của cấu trúc? bạn có thể vui lòng làm rõ nó.
Người dùng

5
@User Plz cũng tham khảo cái này. Nếu bạn vẫn chưa rõ, vui lòng đến để được trợ giúp stackoverflow.com/questions/11772553/…
Jeyaram

Bất cứ ai nói rằng những byte đệm này là vô nghĩa đều không biết rằng truy cập dữ liệu bị lệch là một điều kỳ lạ của kiến ​​trúc x86. Những byte này là cần thiết để tránh các trường hợp ngoại lệ khi bộ xử lý cố gắng tải - ví dụ một số nguyên - dữ liệu nằm giữa ranh giới liên kết tự nhiên của nó.
Tanveer Badar

86
  • packedcó nghĩa là nó sẽ sử dụng không gian nhỏ nhất có thể cho struct Ball- tức là nó sẽ nhồi nhét các trường vào nhau mà không cần đệm
  • alignednghĩa là mỗi cái struct Ballsẽ bắt đầu trên ranh giới 4 byte - tức là đối với bất kỳ struct Ball, địa chỉ của nó có thể được chia cho 4

Đây là các phần mở rộng GCC, không phải là một phần của bất kỳ tiêu chuẩn C nào.


17

Thuộc tính packedcó nghĩa là trình biên dịch sẽ không thêm phần đệm giữa các trường của struct. Padding thường được sử dụng để làm cho các trường được căn chỉnh theo kích thước tự nhiên của chúng, vì một số kiến ​​trúc áp đặt các hình phạt đối với truy cập không được căn chỉnh hoặc hoàn toàn không cho phép.

aligned(4) có nghĩa là cấu trúc phải được căn chỉnh thành một địa chỉ chia hết cho 4.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.