GCC 4 7 version 位元組對齊

2021-06-23 07:27:32 字數 2656 閱讀 4651

1、位域對齊

3.7版本之後gcc都預設使用了-mms-bitfields,此選項意義為使用microsoft的方式進行對齊操作,其對齊策略為將對所有型別相同的位域合併到一起。與之相對的是gcc對其方式,其對齊策略為將所有位域合併到一起,並不區分位域型別。

如下例:

[cpp]view plain

copy

print?

struct  

struct

mircrosoft對齊方式將合併型別相同的a、b,為之分配8個位元組,而對於c,則單獨分配8個位元組,所以上述結構體在此對齊方式下大小為16.

gcc對齊方式將不區分型別合併所有的位域,並根據原型別中最大尺寸分配位域儲存所需的位元組數。譬如對於上述結構,最大尺寸為long long,所以上述結構體大小為8.

此結論可以通過為struct新增不同的gcc結構屬性測試得到。

[cpp]view plain

copy

print?

struct fields __attribute__ ((__ms_struct__)); //用於測試microsoft對齊方式。得到sizeof(fields)結果為16。

//}__attribute__ ((__gcc_struct__));//用於測試gcc對齊方式。得到sizeof(fields)結果為8。

struct fields __attribute__ ((__ms_struct__)); //用於測試microsoft對齊方式。得到sizeof(fields)結果為16。

//}__attribute__ ((__gcc_struct__));//用於測試gcc對齊方式。得到sizeof(fields)結果為8。

從gcc與ms(microsoft)的對齊策略可見,gcc的對齊方式相對更加節約儲存空間。

2、結構對齊

先看乙個結構體:

[cpp]view plain

copy

print?

struct struct_ ; 

struct struct_ ;

此結構體使用預設的gcc選項編譯後,既缺省使用-mms-bitfields選項的情況下,將得到大小為9位元組的儲存空間。

這是因為對於32位作業系統,gcc預設對齊位元組為4位元組,在使用ms結構對齊策略的情況下,gcc在處理第乙個變數時保持其尺寸不變,既為1位元組,在處理第二個變數時同樣保持其尺寸不變,既為4位元組,在處理第三個也是最後乙個變數時,擴充套件其尺寸至對齊尺寸4位元組。因此最後得到的總結構大小為1+4+4=9位元組。

總而言之,ms的對齊策略僅對結構中最後乙個變數起作用。

如果關閉預設的ms對齊策略(通過為gcc新增-mno-ms-bitfields引數),轉而使用gcc的對齊策略,上述結構的尺寸將會是多少?

測試的結果是:12。為何?這是因為gcc將對齊策略應用在了結構體中的每個變數上,對於非4位元組的整數倍的char型別變數first[1]、third[2],gcc都將其擴充套件為4個位元組,對於second,由於其型別大小為4位元組,所以gcc保持其大小不變。擴充套件完成後,結構體的大小為:4+4+4=12位元組。

3、強制設定對齊方式

位元組對齊有利於整塊讀取資料,提高資料吞吐量,但是這是在犧牲存空間的情況下得到的,而在實際應用中,比如網路環境下,為了減少資料傳輸量,我們並不希望使用位元組對齊方式,這時需要關閉位元組對齊。

在程式的移植過程中,比如將32bit系統下的程式移植到64bit系統下,原有的位元組對齊方式可能無法達到提高資料吞吐的目的,因此,我們需要更改位元組對齊方式。

如何關閉?如何更改?

gcc提供了幾種方式:

3.1、通過屬性方式改變:

__attribute__ ((__ms_struct__)) 指定使用ms對齊策略

__attribute__ ((__gcc_struct__)) 指定使用gcc對齊策略

__attribute__ ((__packed__)) 指定使用最少儲存空間對齊策略:合併所有位、對變數使用單位元組方式對齊。

3.2、通過識別符號宣告方式:

#pragma pack(n) 設定對齊方式為n位元組。

#pragma pack() 設定對齊方式為上一次對齊方式。

#pragma pack(push[, n]) 儲存當前對齊方式並設定對齊方式為n位元組。

#pragma pack(pop) 恢復最近一次儲存的對齊方式。

對於i386構架,gcc專門提供了如下3個宣告控制對齊方式:

#pragma ms_struct on 啟用ms對齊方式。

#pragma ms_struct off 關閉ms對齊方式。

#pragma ms_struct reset 重置當前對齊方式為預設對齊方式。

3.3 通過設定gcc編譯引數方式:

-fpack-struct[=n] 設定對齊方式為n位元組對齊,不帶」=n「時預設為4位元組對齊。

-mno-ms-bitfields 關閉ms對齊策略,使用gcc對齊策略。

GCC 4 7 version 位元組對齊

1 位域對齊 3.7版本之後gcc都預設使用了 mms bitfields,此選項意義為使用microsoft的方式進行對齊操作,其對齊策略為將對所有型別相同的位域合併到一起。與之相對的是gcc對其方式,其對齊策略為將所有位域合併到一起,並不區分位域型別。如下例 struct mircrosoft對...

傻瓜式安裝 公升級GCC 4 7

無論出於對c 0x或是openmp等的支援,使用最新的gcc都應是可能情況下的最好選擇。網上其他的教程都過於繁瑣或者因為太老而無法實行,這篇文章主要是簡化了gcc依賴庫的步驟。我是在gcc 4.1.2上公升級,cpu e5606大約用了兩個小時,可以參考上面的文章或者直接用以下指令碼。gcc v指定...

公升級Ubuntu 12 04下的gcc到4 7

我們知道c 11標準開始支援類內初始化 in class initializer qt creator編譯出現error,不支援這個特性,原因在於,ubuntu12.04預設的是使用gcc4.6,而只有gcc4.7才支援c 11,使用如下辦法公升級ubuntu 12.04下的gcc 更新ubuntu...