1. 程式人生 > >Windows下struct和union位元組對齊設定以及大小的確定(一 簡介和結構體大小的確定)

Windows下struct和union位元組對齊設定以及大小的確定(一 簡介和結構體大小的確定)

在windows下設定位元組對齊大小的方式,目前我瞭解有三種:

1. 在編譯程式時候的編譯選項  /Zp[n],如 cl /Zp4 表示對齊大小是4位元組;

2. 預處理命令   #pragma pack( [ show ] | [ push | pop ] [, identifier ] , n  );

3. 微軟特定命令  __declspec(align(#))。

下面我將分別介紹這三種,並分析不同方式的優缺點,先明確下位元組對齊大小都是2的指數倍如1,2,4,8,16,32等。

方法一的用法最為簡單,只需要在編譯選項設定就行,該方式將作用於整個模組,因此是全域性性的,不夠靈活。

方法二的用法複雜點,但該方法可以在一個模組中不斷的設定位元組對齊大小,靈活性很強,針對不同的結構體採用不同的對齊大小,很適合這種方法,但用法較為複雜。

方法三的方法主要是作用於整個結構體上,是加強了位元組對齊的限制,如將整個結構體對齊為64位元組,不管裡面元素總的大小,則結構體大小為大於總大小的最小的64倍數。

結構體大小的確定以及每個元素位置的確定:

對齊大小為 align(方法一和方法二設定的值,在vs2013中預設為8位元組)、結構體中元素位元組最大為max、結構體對齊align_struct(由方法三進行設定)

       假設記憶體是一個一個籃子用於存放結構體的每個變數, 而籃子肯定有大小   = min(align, max)大小為對齊大小和元素位元組最大的 較小者。

下面就是將元素放入籃子的問題,有個原則是:

"The alignment of a member will be on a boundary that is either a multiple ofn

or a multiple of the size of the member, whichever is smaller."

每個元素放置的位置 要麼是 對齊大小的整數倍,要麼是 該元素大小的整數倍,比較這兩個值,哪個小就放在那。

若沒有方法三設定,則最後結構體的大小就為籃子 大小的倍數,若有方法三的設定最後在考慮結構體整體的位元組對齊。下面舉個例子:

typedef struct A
{
	char ca;
	int ib;
	short sc;
	int  id;
	double de;
}A;

若對齊大小align=4, 則 max = 8 = sizeof(double), 籃子大小為 min(4,8) = 4.

char ca 放在第一個籃子中, 偏移為0

int ib 要放在的位置必須為4的倍數,所以放在第二個籃子中,偏移為4

short sc 要放在的位置為2的倍數, 所以放在第三個籃子中,偏移為8

       int id要放在位置為4的倍數, 第三個籃子沒有這樣的位置,所以放在第四個籃子中,偏移為12

      double要放在位置為4的倍數,放在第五個籃子和第六個籃子中,偏移為16,

可以看出總共用了6個籃子,總大小sizeof(A) = 24.

若新增方法三在結構體上 如下

typedef struct __declspec( align( 32) ) A
{
	char ca;
	int ib;
	short sc;
	int  id;
	double de;
}A;
修飾結構體的對齊大小為32,則sizeof(A) = 32 ,但每個元素在該結構體中偏移和上面都一樣,只是在結構體的末尾新增位元組用於對齊。

      現在只是簡單介紹了三種方法和結構體大小的確定 ,將在後面具體介紹方法二和方法三的用法。