1. __attribute__ ((packed)) 的做用就是告訴編譯器取消結構在編譯過程當中的優化對齊,按照實際佔用字節數進行對齊,是GCC特有的語法。這個功能是跟操做系統不要緊,跟編譯器有關,gcc編譯器不是緊湊模式的,我在windows下,用vc的編譯器也不是緊湊的,用tc的編譯器就是緊湊的。例如:html
在TC下:struct my{ char ch; int a;} sizeof(int)=2;sizeof(my)=3;(緊湊模式)windows
在GCC下:struct my{ char ch; int a;} sizeof(int)=4;sizeof(my)=8;(非緊湊模式)數組
在GCC下:struct my{ char ch; int a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5網絡
2. __attribute__關鍵字主要是用來在函數或數據聲明中設置其屬性。給函數賦給屬性的主要目的在於讓編譯器進行優化。函數聲明中的__attribute__((noreturn)),就是告訴編譯器這個函數不會返回給調用者,以便編譯器在優化時去掉沒必要要的函數返回代碼。數據結構
GNU C的一大特點就是__attribute__機制。__attribute__能夠設置函數屬性(Function Attribute)、變量屬性(Variable Attribute)和類型屬性(Type Attribute)。
__attribute__書寫特徵是:__attribute__先後都有兩個下劃線,而且後面會緊跟一對括弧,括弧裏面是相應的__attribute__參數。
__attribute__語法格式爲:
__attribute__ ((attribute-list))
其位置約束:放於聲明的尾部「;」以前。
函數屬性(Function Attribute):函數屬性能夠幫助開發者把一些特性添加到函數聲明中,從而可使編譯器在錯誤檢查方面的功能更強大。__attribute__機制也很容易同非GNU應用程序作到兼容之功效。
GNU CC須要使用 –Wall編譯器來擊活該功能,這是控制警告信息的一個很好的方式。
packed屬性:使用該屬性可使得變量或者結構體成員使用最小的對齊方式,即對變量是一字節對齊,對域(field)是位對齊。架構
若是你看過GPSR協議在TinyOS中的實現,你必定會注意到下面的語句:
typedef struct {
double x;
double y;
} __attribute__((packed)) position_t;函數
開始咱們還能夠理解,不久是定義一個結構體嘛!不過看到後面的語句,你可能就會一頭霧水了,’ __attribute__((packed))’是什麼東西?有什麼做用?一連串的疑問立刻就會從你腦殼裏冒出來。雖然這個對理解整個程序沒有什麼影響,但我不想讓這些疑問一直呆在個人腦子裏,負擔過重。免得之後念念不忘,並且也許有一天能夠用的上呢。搞清楚這個問題吧!測試
GNU C的一大特點(卻不被初學者所知)就是__attribute__機制。__attribute__能夠設置函數屬性(Function Attribute)、變量屬性(Variable Attribute)和類型屬性(Type Attribute)。
__attribute__語法格式爲:
__attribute__ ((attribute-list))優化
其位置約束爲:放於聲明的尾部「;」以前。ui
packed是類型屬性(Type Attribute)的一個參數,使用packed能夠減少對象佔用的空間。須要注意的是,attribute屬性的效力與你的鏈接器也有關,若是你的鏈接器最大隻支持16字節對齊,那麼你此時定義32字節對齊也是無濟於事的。
使用該屬性對struct或者union類型進行定義,設定其類型的每個變量的內存約束。當用在enum類型定義時,暗示了應該使用最小完整的類型(it indicates that the smallest integral type should be used)。
下面的例子中,my-packed-struct類型的變量數組中的值會緊湊在一塊兒,但內部的成員變量s不會被「pack」,若是但願內部的成員變量也被packed的話,my-unpacked-struct也須要使用packed進行相應的約束。
struct my_unpacked_struct
{
char c;
int i;
};
struct my_packed_struct
{
char c;
int i;
struct my_unpacked_struct s;
}__attribute__ ((__packed__));
在每一個系統上看下這個結構體的長度吧。
內存對齊,每每是由編譯器來作的,若是你使用的是gcc,能夠在定義變量時,添加__attribute__,來決定是否使用內存對齊,或是內存對齊到幾個字節,以上面的結構體爲例:
1)到4字節,一樣可指定對齊到8字節。
struct student
{
char name[7];
uint32_t id;
char subject[5];
} __attribute__ ((aligned(4)));
2)不對齊,結構體的長度,就是各個變量長度的和
struct student
{
char name[7];
uint32_t id;
char subject[5];
} __attribute__ ((packed));
轉自http://blog.chinaunix.net/uid-25768133-id-3485479.html