C陷阱篇之enum預設長度

2022-07-17 13:51:23 字數 955 閱讀 8843

**僅用於學習: 

enum型用於定義常量集合,相比#define有一些優勢,如:enum是一種資料型別,使用時會檢查型別匹配;enum增加了範圍約束,避免變數賦值和使用時超出定義範圍。但enum也有乙個隱含問題:enum變數占用的空間與編譯器相關。

多數編譯器預設enum型長度等於int型,很多人也把enum型變數等同於int,但c標準在這裡留下了尾巴:「列舉型尺寸是能夠容納最大枚舉子值的整數尺寸」,「列舉型別中枚舉子的值必須要能用乙個int型表述」。也就是說,列舉型的尺寸不能超過int型,但不必等於int型,只要能容納最大枚舉子就行,下例:

enum etype1 ;

enum etype2 ;

這兩個列舉型別最小可用char、short的記憶體空間表示,即有可能:

sizeof( etype1 ) == sizeof( char );

sizeof( etype2 ) == sizeof( short );

一些編譯器為節約記憶體可以設定這種「量體裁衣」的策略。如ads就有圖示選項(enum container always int),選定後enum變數長度為int,否則就等於能容納最大枚舉子的最短長度。gcc也有類似選項-fshort-enums,預設不設定,一旦設定就選用節省記憶體的enum長度。

enum長度不確定會帶來可移植性問題,如果第三方庫api介面使用enum型別,編譯和呼叫庫時一旦有關enum長度的編譯器設定不一致,api介面層對數值的解析就不匹配。比如上層應用編譯時沒有用-fshort-enums,預設用4位元組空間來儲存使用enum變數,而編譯庫時設定了fshort-enums,則庫內部此enum size可能為1。當把enum變數位址傳進api時,內部只修改變數最低位元組,高3位元組值無變化(內容隨機),api返回時,上層使用的4位元組enum變數值就可能隨機。(潛規則篇之api介面)

C陷阱篇之enum預設長度

enum型用於定義常量集合,相比 define有一些優勢,如 enum是一種資料型別,使用時會檢查型別匹配 enum增加了範圍約束,避免變數賦值和使用時超出定義範圍。但enum也有乙個隱含問題 enum變數占用的空間與編譯器相關。多數編譯器預設enum型長度等於int型,很多人也把enum型變數等同...

C陷阱篇之常見手誤

c的某些語法容易讓人不小心觸雷,比如 從0開始的下標 很多高階語言中,定義n個元素的陣列,下標範圍是從1到n,但c特殊,n元素的c陣列中沒有下標為n的元素,只有從0到n 1的下標。所以使用c陣列時不要犯這種錯誤 int i,a 10 for i 1 i 10 i i 10時超出陣列邊界 八進位制or...

C陷阱篇之常見手誤

c的某些語法容易讓人不小心觸雷 很多高階語言中,定義n個元素的陣列,下標範圍是從1到n,但c特殊,n元素的c陣列中沒有下標為n的元素,只有從0到n 1的下標。所以使用c陣列時不要犯這種錯誤 int i,a 10 for i 1 i 10 i i 10時超出陣列邊界 八進位制or十進位制常數 c編譯器...