關於C語言結構體對齊問題的探討

iteye_4515發表於2011-11-30

關於C語言結構體對齊問題的探討

今天跟一個同事聊天中,討論起了C語言結構體對齊的問題,查閱了一些blog,發現這些blog多多少少有些地方忽略了,或者是敘述的不清楚。在這裡,我想做個總結,梳理一下。

先扯點題外話,我在查閱blog的時候,發現很多人都是你抄我,我抄你,一個錯誤到處重現。。。我要問,有意思嗎?寫技術blog是在完任務嗎?希望大家寫blog的時候能參考下面這位大哥的建議,寫出有價值,能幫助別人的東西。

寫技術部落格的注意事項

從理論上看:

位元組對齊的細節和編譯器實現相關,但一般而言,滿足三個準則:
1.結構體變數的首地址能夠被其最寬基本型別成員的大小所整除;
2. 結構體每個成員相對於結構體首地址的偏移量(offset)都是該成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
3. 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充位元組(trailing padding)。

4. 對於結構體巢狀結構體,其對齊仍按照基本資料型別拆分來分析

上面這些條準則在很多blog上都提到過,我想問問這些博主,你們有沒有交代過前三條是windows平臺上的規則?或許這樣說太武斷,但是linux下不能按照

這些“準則”去分析。

在win下這些準則基本上可以讓你搞清許多關於結構體對齊的問題(包括那些噁心的面試題)。

剩下的,像巢狀,#pragma pack(n),位域等,大家可以去google,資料很多。還是那句話,要自己去好好考察下,因為有些博主是不負責任的。

這裡說下GCC下結構體對齊的一些規則:

(offset代表對齊的偏移,T代表基本資料型別, size代表基本型別的大小)

size = sizeof(T)

if (size <= 2) {

offset= size;

} else {

offset= 4;

}

即小於等於2的時候,按照型別本身大小來算,而大於2的型別一律將4作為對齊偏移。

結構體整體的對齊規則按照最大成員大小來定,超過4位元組的,按照4位元組對齊。

剩下的我就不想多說了,有很多blog對這一個話題都有比較好的分析和總結,我就不重複了。這裡給出我發現的一些相對較好blog,供大家參考:

1.關於對齊問題的設計思想、注意事項和相關擴充知識介紹。

http://blog.csdn.net/shenbin1430/article/details/4292463

2.對#pragma pack(n)相關問題做了闡述。

http://www.cppblog.com/Tauruser/archive/2007/02/28/19049.html

3.對含有位域的對齊問題做了探討。

http://blog.csdn.net/xing_hao/article/details/6678048

相關文章