gcc結構體對齊

struct A a=      //gcc支持的一種結構體賦值方式,好處是可以單獨賦值
{                    //結構體變量對齊存放,所以a的大小爲8字節
    .a=4,
    .b=555,
}

// 定義類型的同時定義變量,s1是一個變量。
struct student
{
    char name[20];
    int age;
}s1;

// 將類型struct student重命名爲s1,s1是一個類型名,不是變量
typedef struct student
{
    char name[20];
    int age;
}s1;

s.a = 12;        // 編譯器在內部還是轉成指針式訪問 int *p = s; *(p+0) = 12;
s.b = 44;        // int *p = s; *(p+1) = 44;
s.c = 64;        // int *p = s; *(p+2) = 44;

s1.a = 12;        // int *p = (int *)&s1; *p = 12;
s1.b = 4.4;        // double *p = (double *)(&s1 + 4); *p = 4.4;
s1.c = 'a';        // char *p = (char *)((int)&s1 + 12); *p = 'a';

struct stu
{                            // 1字節對齊    4字節對齊
    char sex;                // 1            4(1+3)
    int length;                // 4            4
    char name[10];            // 10            12(10+2)
};

---gcc支持但不推薦的對齊指令:#pragma pack()   #pragma pack(n) (n=1/2/4/8)
(1)#pragma是用來指揮編譯器,或者說設置編譯器的對齊方式的。編譯器的默認對齊方式是4,但是有時候我不希望對齊方式是4,而希望是別的(譬如希望1字節對齊,也可能希望是8,甚至可能希望128字節對齊)。
(2)常用的設置編譯器編譯器對齊命令有2種:第一種是#pragma pack(),這種就是設置編譯器1字節對齊(有些人喜歡講:設置編譯器不對齊訪問,還有些講:取消編譯器對齊訪問);第二種是#pragma pack(4),這個括號中的數字就表示我們希望多少字節對齊。
(3)我們需要#prgama pack(n)開頭,以#pragma pack()結尾,定義一個區間,這個區間內的對齊參數就是n。
(4)#prgma pack的方式在很多C環境下都是支持的,但是gcc雖然也可以不過不建議使用。

---gcc推薦的對齊指令__attribute__((packed))  __attribute__((aligned(n)))
(1)__attribute__((packed))使用時直接放在要進行內存對齊的類型定義的後面,然後它起作用的範圍只有加了這個東西的這一個類型。packed的作用就是取消對齊訪問。
(2)__attribute__((aligned(n)))使用時直接放在要進行內存對齊的類型定義的後面,然後它起作用的範圍只有加了這個東西的這一個類型。它的作用是讓整個結構體變量整體進行n字節對齊(注意是結構體變量整體n字節對齊,而不是結構體內各元素也要n字節對齊)

---參考閱讀blog:
    http://www.cnblogs.com/dolphin0520/archive/2011/09/17/2179466.html
    http://blog.csdn.net/sno_guo/article/details/8042332
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章